代码更多:
from pprint import pprint
li = []
for i in range(5):
li.append(lambda : pprint(i))
for k in li:
k()
产率:
4 4 4 4 4
为什么不
0 1 2 3 4
...
感谢。
P.S。如果我编写完整的装饰器,它按预期工作:
from pprint import pprint
li = []
#for i in range(5):
#li.append(lambda : pprint(i))
def closure(i):
def _func():
pprint(i)
return _func
for i in range(5):
li.append(closure(i))
for k in li:
k()
答案 0 :(得分:11)
你需要这样做:
lambda i=i: pprint(i)
而是捕获i
答案 1 :(得分:3)
它正确地引用i
,只有事情是,当列表被填充时,i
将在迭代结束时从序列中的最后一项分配值,因此这就是你看到4
的原因。
答案 2 :(得分:3)
如果您不想使用默认参数 - 如果使用参数意外调用可能会引入错误 - 您可以使用嵌套的lambda:
from pprint import pprint
li = []
for i in range(5):
li.append((lambda x: lambda: pprint(x))(i))
for k in li:
k()
这是closure
功能的匿名版本。
答案 3 :(得分:0)
lambda函数在i
变量上创建闭包。第一个for
循环完成后,i
的值为4
。
然后第二个for
循环开始,所有lambda函数都被执行。然后,每个人都会打印i
的当前值,即4
。
答案 4 :(得分:0)
答案:因为lambda中的代码使用的是全局变量i
。
如果删除参数i
,您的第二个变体将与第一个变体使用lambda相同:
def closure():
而不是
def closure(i):
即。函数内部的代码将使用全局变量i
。