Python 採用詞法作用域,變量查找遵循 LEGB 原則:Local(局部) → Enclosing(嵌套) → Global(全局) → Built-in(內建)。理解這四層作用域是掌握 global 和 nonlocal 關鍵字的前提。
def scope_test():
def do_local():
spam = "local spam" # 僅在 do_local 內部有效
def do_nonlocal():
nonlocal spam # 修改外層 scope_test 的 spam
spam = "nonlocal spam"
def do_global():
global spam # 修改模塊級全局 spam
spam = "global spam"
spam = "test spam" # scope_test 的局部變量
do_local()
print("After local assignment:", spam) # 輸出: test spam
do_nonlocal()
print("After nonlocal assignment:", spam) # 輸出: nonlocal spam
do_global()
print("After global assignment:", spam) # 輸出: nonlocal spam(注意:此處仍為 nonlocal 值)
scope_test()
print("In global scope:", spam) # 輸出: global spam
| 階段 | 輸出值 | 說明 |
|---|---|---|
| 局部賦值後 | test spam | do_local 創建新局部變量,不影響外層 |
| nonlocal 賦值後 | nonlocal spam | 修改了 scope_test 的 spam 綁定 |
| global 賦值後 | nonlocal spam | scope_test 內打印仍為其局部值,全局值已改變 |
| 全局作用域 | global spam | 模塊級 spam 被 global 修改 |
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
mc = make_counter()
print(mc()) # 1
print(mc()) # 2
print(mc()) # 3
nonlocal 使內部函數能修改外層函數的變量,構成閉包,實現狀態保持。這是函數式編程中常用模式。
nonlocalglobal,優先考慮類或模塊級單例模式