Python闭包捕获变量引用而非值,内部函数调用时访问外部变量当前值;循环中创建闭包易共享同一变量导致错误,可用默认参数或闭包工厂解决。
Python 闭包捕获的是变量的引用,而不是创建时的值。这意味着内部函数在调用时访问的是外部作用域中该变量的当前值,而非定义闭包时的快照。
当一个嵌套函数引用了外层函数的局部变量,并且这个嵌套函数在外部函数返回后仍能访问该变量,就形成了闭包。Python 不会复制变量内容,而是将变量名绑定到外层作用域中的对象上。只要该对象还存在,闭包就能通过引用访问它。
在 for 循环中定义闭包时,所有闭包共享同一个变量引用,容易导致意外结果:
funcs = []
for i in range(3):
funcs.append(lambda: i)
print([f() for f in funcs]) # 输出 [2, 2, 2],不是 [0, 1, 2]这是因为所有 lambda 都引用了同一个 i,而循环结束时 i == 2。
lambda x=i: x
可以通过函数对象的 __closure__ 属性观察闭包引用:
func.__closure__ 是一个元组,每个元素是 cell 对象cell.cell_contents 可读取当前引用的对象值__closure__ 为 None
被闭包引用但不在内部函数中定义的变量,称为“自由变量”。Py

UnboundLocalError
nonlocal 声明),Python 会将其视为局部变量,导致引用错误