您无法在Python 2中对闭包变量进行突变。在Python 3中,由于您使用了它print()
,您可以声明它们nonlocal
:
def foo():
counter = 1
def bar():
nonlocal counter
counter += 1
print("bar", counter)
return bar
bar = foo()
bar()
否则,内部的赋值bar()
将使变量成为本地变量,并且由于您尚未在本地范围内为变量赋值,因此尝试访问它是错误的。
在Python 2中,我最喜欢的解决方法如下:
def foo():
class nonlocal:
counter = 1
def bar():
nonlocal.counter += 1
print("bar", nonlocal.counter)
return bar
bar = foo()
bar()
这是可行的,因为诱变可变对象不需要更改变量名称指向的对象。在这种情况下,nonlocal
闭包变量是,并且永远不会重新分配。仅其内容被更改。其他解决方法使用列表或词典。
或者,您可以对整个过程使用一个类,就像@naomik在评论中建议的那样。定义__call__()
以使实例可调用。
class Foo(object):
def __init__(self, counter=1):
self.counter = counter
def __call__(self):
self.counter += 1
print("bar", self.counter)
bar = Foo()
bar()