Python 使用闭包来捕获对原始变量的引用。lambda
对象保留对名称的引用,i
通过它可以访问值。这意味着i
变量在完成后继续存在f
。
.__closure__
您可以在 lambda 对象的元组中内省此闭包;函数具有相同的属性:
>>> L[0].__closure__
(<cell at 0x1077f8b78: int object at 0x107465880>,)
>>> L[0].__closure__[0]
<cell at 0x1077f8b78: int object at 0x107465880>
>>> L[0].__closure__[0].cell_contents
4
这也是为什么列表中的所有lambda都L
引用 value 4
,而不是数字 0 到 4 的原因。它们都引用同一个闭包:
>>> L[0].__closure__[0] is L[1].__closure__[0]
True
闭包是指变量,而不是定义闭包时该变量的值。在循环结束i
时最后设置为4
,因此当i
在 lambda 闭包中查找时,4
将找到列表中的所有 lambda。
i
如果您希望您的 lambda在循环期间引用 的值,请在关键字参数中捕获它:
def f():
L = []
for i in range(5):
L.append(lambda x, i=i: i ** x)
return L
Nowi
是 lambda 的局部变量,而不是闭包。
或者,创建一个全新的范围来绘制闭包:
def create_lambda(i):
return lambda x: i ** x
def f():
return [create_lambda(i) for i in range(5)]
现在create_lambda()
是一个新的范围,它有自己的本地i
供 lambda 闭包引用。然后每个 lambdas 都有自己的闭包:
>>> L[0].__closure__[0] is L[1].__closure__[0]
False
闭包是指特定命名空间中的变量;每次调用函数时都会创建一个新的本地命名空间,因此每个闭包都在一个单独的命名空间中引用i
in与其他对.create_lambda
create_lambda