有Python 2.7函数记住值而不是引用?闭合怪异 [英] Have Python 2.7 functions remember value and not reference? Closure Weirdness

查看:129
本文介绍了有Python 2.7函数记住值而不是引用?闭合怪异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从一个函数返回一个函数列表,每个函数使用来自外部作用域的变量。这不工作。这里有一个例子演示了发生了什么:

  a = [] 
在范围$ 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, so i is 9 in all of the lambdas because that's the value of i 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 variable i 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆