【发布时间】:2015-07-17 02:39:29
【问题描述】:
考虑以下 Python 3 指令
res = []
for a in range(3) :
res.append(lambda n : n + a)
目的是构建一个列表res,其中包含三个函数res[0]、res[1] 和res[2],使得res[i](n) 返回n + i,对于[0, 1, 2] 中的所有i。
但是,一个人得到了
>>> res[0](0)
2
而不是
>>> res[0](0)
0
一个也有
>>> res[1](2)
4
对此行为的解释是,在示例的任何动态生成的匿名函数的主体中的表达式n + a 中,符号a 在函数创建时不会被计算。评估在 for 语句的出口处执行,解释了为什么所有函数 res[0]、res[1] 和 res[2] 返回它们的参数值加上 2è (becauseabrowsesrange(3)and2 ` 是它的最后一个值)。
请注意,问题不在于我们使用匿名函数这一事实。确实,说明书
res = []
for a in range(3) :
def f(n) :
return n + a
res.append(f)
导致相同的行为。
还请注意,我们可以通过使用 Python 的函数 eval 来实现上述目标:
res = []
for a in range(3) :
s = "lambda n : n + %s" %(a)
res.append(eval(s))
诀窍在于a 的动态值被考虑用于创建res 的每个函数。
现在我的问题是
- 这是错误还是功能?
- 是否有其他方法不通过
eval来获得预期的行为?
【问题讨论】:
-
这能回答你的问题吗? What do (lambda) function closures capture?