python闭包行为怪异

2024-09-26 04:42:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试Lexical closures in Python中问题中的一段代码

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

for f in flist:
    print f.func_closure

输出为:

^{pr2}$

不是吗?公司名称:

(<cell at 0x9222d94: int object at 0x8cabdbc>,)
(<cell at 0x9222d94: int object at 0x8cabdbc>,)
(<cell at 0x9222d94: int object at 0x8cabdbc>,)

我使用以下代码得到了上述输出:

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

for f in flist:
    print f.func_closure

我使用的是python2.6.6(r266:842922010年9月15日,15:52:39)。在


Tags: 代码inforreturnobjectdefcellat
3条回答

language reference指定func_closure是“一个包含函数自由变量绑定的单元格的元组。”

现在,请注意两个版本之间的区别:在第一个版本中,i是一个模块级(即全局)变量。评估每个函数的结果是相同的:

>>> [f(2) for f in flist]
[4, 4, 4]

在每个函数中,i不是自由的,而是引用全局的i,因此不,输出不应该是非零长度元组的列表。在

实际上,您可能不关心func_closure的值,除非您在做一些相当深奥的魔术。如果您正在做一些神奇的事情,请注意,在给定规范的情况下,如果没有自由变量,func_closure不应该是空元组,那么如果您希望您的代码能够在甚至不同的python版本之间移植,那么就要适当地处理这种情况。在

只有在全局(模块)范围之外引用变量时才会引入闭包:

>>> def foo():
...     def bar(): pass
...     return bar
...
>>> foo().func_closure is None
True
>>> spam = 'eggs'
>>> def foo():
...     def bar(): return spam
...     return bar
...
>>> foo().func_closure is None
True

只有当内部函数引用周围范围内的变量时,才会生成闭包:

^{pr2}$

请注意,实际上必须引用周围范围中的变量。简单地忽略作用域会再次给您None

>>> def foo():
...     spam = 'eggs'
...     def bar(): pass
...     return bar
...
>>> foo().func_closure is None
True

在第一个示例中,i是一个模块范围变量,只有在第二个示例中,才会通过将代码包装在新函数actualFact中来引入新的范围。在

一种不需要关闭的廉价方法

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

相关问题 更多 >