use*_*676 1 python closures python-3.x
为什么lambda函数获取值列表i = 4.在调用lambda期间,封闭范围不存在.函数f已完成工作并返回控制(变量i不存在).
def f():
L = []
for i in range(5):
L.append(lambda x: i ** x)
return L
L = f()
L[0]
def f1(N):
def f2(X):
return X**N
return f2
f=f1(2)
f (3)
9
g = f1(3)
g(3)
27
f(3)
9
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这也是列表中所有 lambdas L引用值的原因4,而不是数字0到4的原因.它们都引用相同的闭包:
>>> L[0].__closure__[0] is L[1].__closure__[0]
True
Run Code Online (Sandbox Code Playgroud)
闭包是指变量,而不是定义闭包时该变量的值.在循环的i最后设置为4,所以当查找ilambda闭包时,4将找到列表中的所有lambdas.
如果您希望lambdas引用i循环期间的值,请在关键字参数中捕获它:
def f():
L = []
for i in range(5):
L.append(lambda x, i=i: i ** x)
return L
Run Code Online (Sandbox Code Playgroud)
现在i是lambda的局部变量,而不是闭包.
或者,创建一个全新的范围来绘制闭包:
def create_lambda(i):
return lambda x: i ** x
def f():
return [create_lambda(i) for i in range(5)]
Run Code Online (Sandbox Code Playgroud)
现在create_lambda()是一个新的作用域,它有自己的本地i用于lambda闭包引用.lambdas然后每个都有自己的闭包:
>>> L[0].__closure__[0] is L[1].__closure__[0]
False
Run Code Online (Sandbox Code Playgroud)
闭包引用特定命名空间中的变量; 每次调用一个新的本地命名空间创建一个功能,所以每个封闭是指i在create_lambda从其他调用不同的命名空间create_lambda.
| 归档时间: |
|
| 查看次数: |
197 次 |
| 最近记录: |