0%

namespace與LEGB scope規則

python的namespace是一種”name-to-object”的對應關係,而在不同的namespace之間都有各自的作用域,就像是不同的module中雖然都定義了相同的名稱的函式,但卻不會互相影響。為了找到特定的”name-to-object”的namespace,python會採用scope的概念來找到特定object的所屬變數或是函式,而搜尋順序即是LEBG規則。

python的scope規則LEGB查找順序分別為 Local -> Enclosed -> Global -> Built-in

Local: 宣告於於function或是class內的name
Enclosed: 封閉的function,function被另一個function包起來,常見為Closure
Global: 最上層位於module的global name
Build-in: 內建module的name,例如print, input等等

以下舉幾個範例說明:

1. L - local scope
1
2
3
4
5
6
7
var = 'global'    
def L():
var = 'local'
print(var)

>>>> L() # local 當function有定義local scope時,會優先使用local scope
local
2. LE - local and Enclosed scope
1
2
3
4
5
6
7
8
9
var = 'global'
def LE():
var = 'enclosed'
def inner():
print(var)
inner()

>>>> LE() # 當function沒有local scope時,會往外找enclosed scope
enclosed
3. LEG - local, Enclosed and Global scope
1
2
3
4
5
6
var = 'global'
def LEG():
print(var)

>>> LEG() # 當local和enclosed都沒有時,會往外找global
global
4. LEGB - local, Enclosed, Global and Build-in scope
1
2
3
4
5
6
7
8
9
10
def id(var):    
return 'global id()'

def LEGB(var):
print(id(var))
print(str(var))

>>> LEGB('Build-in str()') # 當有定義global function,會呼叫global function,否則會呼叫Build-in function
global id()
Build-in str()
5. NameError - name is not defined
1
2
3
4
5
6
>>> var = 'global'
>>> print(var2) # 當LEGB scope都找不到,會發生NameError
Traceback (most recent call last):
File “LEGB.py”, line 39, in <module>
print(var2)
NameError: name 'var2' is not defined

以上幾個是python LEGB scope順序的範例,了解LEGB的觀念也有助於幫助自己在開發的時候,避免誤用scope產生許多bug

參考資料:
A Beginner’s Guide to Python’s Namespaces, Scope Resolution, and the LEGB Rule
Python docs - Scopes and Namespace