LEGB是Python中變量查找的重要概念。本文通過概念和試題的形式,視圖形象的解釋LEGB在Python中的應(yīng)用。
例題
《核心編程(第二版)》變量作用域和命名空間一節(jié)有以下一道題目:
# coding=utf-8
#!/usr/bin/env python
def proc1():
j,k = 3,4
print "j == %d and k == %d" % (j,k)
k = 5
def proc2():
j = 6
proc1()
print "j == %d and k == %d" % (j,k)
k = 7
proc1()
print "j == %d and k == %d" % (j,k)
j = 8
proc2()
print "j == %d and k == %d" % (j,k)
請問輸出結(jié)果是什么?要想解這道題,必須先了解Python中的一些概念。
LEGB
Python 的變量名解析機(jī)制有時稱為LEGB。
L: Local 是函數(shù)內(nèi)的名字空間,包括局部變量和形參
E: Enclosing 外部嵌套函數(shù)的名字空間(閉包中常見)
G: Global 全局變量,函數(shù)定義所在模塊的名字空間
B: Builtin 內(nèi)置模塊的名字空間
查找的順序?yàn)椋篖--->E--->G--->B

查找一個x 的變量,Python 首先在函數(shù)內(nèi)部,局部(Local)范圍來查找這個變量;
如果沒有找到,則到包含這個函數(shù)定義的外圍去查找(稱作 Enclosing),這個外圍或許是另外一個函數(shù)(包括匿名函數(shù))。
如果還是沒有,繼續(xù)朝外查找,一直到模塊級別,從這里定義了全局(Global)變量中尋找;
如果仍然沒有找到,則查找 Python 內(nèi)置變量(Built-in),看是否有相同名字的。
注:在上述查找過程中,一旦變量找到,就不再繼續(xù)朝外圍查找。也就是說 LEGB 同時也定義了從 L 到 B 得優(yōu)先級。
題解
上題目輸出結(jié)果如下:
j == 3 and k == 4
name 'j' is not defined
j == 3 and k == 4
j == 6 and k == 7
j == 8 and k == 7
具體解釋如下:
- proc1() 函數(shù)內(nèi)部就有j,k,停止向上查找,故j == 3 and k == 4
- print "j == %d and k == %d" % (j,k),程序從上往下執(zhí)行,當(dāng)前只定義k=7,j還未定義,因?yàn)橐呀?jīng)是全局變量了,Builtin中未定義j,因此返回未定義的錯誤。
- proc2()中會調(diào)用proc1()依舊先打印j == 3 and k == 4
proc2()內(nèi)部需要打印,j,k值,j本地已經(jīng)定義為6,k未定義,則向上查找,查找到全局變另種定義了k=7,因此輸出:j == 6 and k == 7 - print "j == %d and k == %d" % (j,k),前面的程序已經(jīng)給j,k進(jìn)行了賦值,直接輸出即可,j == 8 and k == 7
來源參考:
理解 Python 的 LEGB
零基礎(chǔ)學(xué)python-16.3 變量名解析:LEGB原則
本文由 EverFighting 創(chuàng)作,采用 **知識共享署名 3.0 中國大陸許可協(xié)議 **進(jìn)行許可。