有Python 2.7函数记住值而不是引用?闭合怪异 [英] Have Python 2.7 functions remember value and not reference? Closure Weirdness
问题描述
我试图从一个函数返回一个函数列表,每个函数使用来自外部作用域的变量。这不工作。这里有一个例子演示了发生了什么:
a = []
$ p $为什么会发生这种情况,如何在python 2.7中解决?
在范围$ b a.append(lambda x:x + i)
a [1](1)#返回10,它似乎应该返回2
解决方案
i
每次都引用相同的变量,因此i
在所有lambdas中为9,因为这是循环结束时i
的值。最简单的解决方法涉及默认参数:lambda x,i = i:x + i
这会将循环
i
的值绑定到局部变量
另一个解决方法是定义一个lambda,定义另一个lambda,并调用第一个lambda:
(lambda i:lambda x:x + i)(i)
如果你考虑这一点,这种行为会更有意义:
def outerfunc():
def innerfunc():
return x + i
a = []
for i在范围
a.append(innerfunc)
return a
$ c> innerfunc 定义一次,所以直观地说,你只使用一个单一的函数对象,你不会期望循环创建十个不同的闭包。对于一个lambda,它不像看起来像函数只定义一次,它看起来像你通过循环定义它每次新鲜,但实际上它是功能上相同的长版本。
I'm trying to return from a function a list of functions, each of which uses variables from the outside scope. This isn't working. Here's an example which demonstrates what's happening:
a = [] for i in range(10): a.append(lambda x: x+i) a[1](1) # returns 10, where it seems it should return 2
Why is this happening, and how can I get around it in python 2.7 ?
解决方案The
i
refers to the same variable each time, soi
is 9 in all of the lambdas because that's the value ofi
at the end of the loop. Simplest workaround involves a default argument:lambda x, i=i: x+i
This binds the value of the loop's
i
to a local variablei
at the lambda's definition time.Another workaround is to define a lambda that defines another lambda, and call the first lambda:
(lambda i: lambda x: x+i)(i)
This behavior makes a little more sense if you consider this:
def outerfunc(): def innerfunc(): return x+i a = [] for i in range(10): a.append(innerfunc) return a
Here,
innerfunc
is defined once, so it makes intuitive sense that you are only working with a single function object, and you would not expect the loop to create ten different closures. With a lambda it doesn't look like the function is defined only once, it looks like you're defining it fresh each time through the loop, but in fact it is functionally the same as the the long version.这篇关于有Python 2.7函数记住值而不是引用?闭合怪异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!