你不能在Python 2中改变闭包变量.在Python 3中,由于你的print(),你似乎正在使用它,你可以声明它们是非本地的:
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()