关于python闭包 [英] About python closure

查看:103
本文介绍了关于python闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我从某人的博客中得到的一个关于python闭包的例子。
我在python 2.7运行它,并得到不同于我期望的输出。

Below is an example I got from someone's blog about python closure. I run it in python 2.7 and get a output different from my expect.

flist = []

for i in xrange(3):
    def func(x):
        return x*i
    flist.append(func)

for f in flist:
    print f(2)

我的预期输出是:0,2 ,4

但输出是:4,4,4

有没有人可以帮助解释它?

提前感谢。

My expected output is: 0, 2, 4
But the output is: 4, 4, 4
Is there anyone could help to explain it?
Thank you in advance.

推荐答案

循环不会在Python中引入范围,因此所有三个函数都关闭相同的 i 变量,并且在循环结束后将引用它的最终值,这是2。

Loops do not introduce scope in Python, so all three functions close over the same i variable, and will refer to its final value after the loop finishes, which is 2.

似乎几乎所有我跟谁使用Python中的闭包被咬了。推论是,外部函数可以改变 i ,但内部函数不能(因为这将使 i 基于Python语法规则的闭包)。

It seems as though nearly everyone I talk to who uses closures in Python has been bitten by this. The corollary is that the outer function can change i but the inner function cannot (since that would make i a local instead of a closure based on Python's syntactic rules).

有两种方法可以解决这个问题:

There are two ways to address this:

# avoid closures and use default args which copy on function definition
for i in xrange(3):
    def func(x, i=i):
        return x*i
    flist.append(func)

# or introduce an extra scope to close the value you want to keep around:
for i in xrange(3):
    def makefunc(i):
        def func(x):
            return x*i
        return func
    flist.append(makefunc(i))

# the second can be simplified to use a single makefunc():
def makefunc(i):
    def func(x):
        return x*i
    return func
for i in xrange(3):
    flist.append(makefunc(i))

# if your inner function is simple enough, lambda works as well for either option:
for i in xrange(3):
    flist.append(lambda x, i=i: x*i)

def makefunc(i):
    return lambda x: x*i
for i in xrange(3):
    flist.append(makefunc(i))

这篇关于关于python闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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