彻底搞懂 Python 作用域:LEGB 规则的 3 个实战误区与解决方案
·
LEGB 规则核心概念
Python 作用域遵循 LEGB(Local → Enclosed → Global → Built-in)查找顺序。局部变量优先于闭包函数外的嵌套作用域变量,全局变量次之,最后查找内置命名空间。
误区一:循环中的变量泄露
错误现象for 循环或列表推导式中定义的变量会泄露到外部作用域,导致后续代码意外覆盖变量:
for i in range(3):
pass
print(i) # 输出 2 而非报错
解决方案
使用函数隔离作用域或明确删除变量:
def process_data():
for j in range(3):
pass
process_data()
print(j) # 报错 NameError
误区二:闭包延迟绑定
错误现象
闭包中引用的外部变量在函数调用时才被解析,可能导致非预期结果:
funcs = []
for k in range(3):
funcs.append(lambda: print(k))
for f in funcs:
f() # 全部输出 2
解决方案
通过默认参数立即绑定当前值,或使用 functools.partial:
funcs = []
for k in range(3):
funcs.append(lambda k=k: print(k))
for f in funcs:
f() # 输出 0,1,2
误区三:全局变量修改未声明
错误现象
函数内修改全局变量未使用 global 声明时,会创建同名的局部变量:
count = 0
def increment():
count += 1 # UnboundLocalError
increment()
解决方案
显式声明全局变量或通过参数传递:
count = 0
def increment():
global count
count += 1
increment()
动态作用域检查工具
使用 globals() 和 locals() 实时查看作用域变量:
def debug_scope():
var = "local"
print(locals()) # {'var': 'local'}
print(globals().get('count')) # 0
debug_scope()
通过 nonlocal 修改嵌套作用域变量时,需确保外层函数已定义该变量。
更多推荐



所有评论(0)