1

可能重复:
(lambda)函数闭包在 Python 中捕获了什么?

使用此代码:

def problem():
    PHI_LIST_0 = [lambda a, b: a+b+u for u in xrange(3)]
    PHI_LIST_1 = [lambda a, b: a+b+0, lambda a, b: a+b+1, lambda a, b: a+b+2]

    for phi in PHI_LIST_0: print "v0:", phi(1,1)
    print
    for phi in PHI_LIST_1: print "v1:", phi(1,1)

if __name__ == '__main__':
    problem()

我得到:

v0: 4
v0: 4
v0: 4

v1: 2
v1: 3
v1: 4

预期的行为是最后一个行为,带有 PHI_LIST_1。我想我理解为什么结果与 PHI_LIST_0 不同:可能是因为 Python 在评估 phi(1,1) 时使用了最后一个“u”,即 2。

但是我想以定义 PHI_LIST_0 的方式声明一个函数列表,并带有列表理解。有人知道我该怎么做吗?

4

1 回答 1

2

当你定义一个函数时,它会在函数体中的自由变量上创建一个闭包。在您的 PHI_LIST_0 中,这就是变量u。它不保留 u 的值,它保留对名称 u 的引用。当您调用该函数时,它使用 u 的当前值。因此,您的所有函数都引用同一个变量,并且都看到它的相同(最后一个)值,因此它们的行为都相同。

您可以使用默认值技巧解决此问题:

PHI_LIST_0 = [lambda a, b, u=u: a+b+u for u in xrange(3)]

现在 u 参数的默认值在定义函数时计算,并与函数一起存储。

于 2012-12-11T15:45:24.040 回答