You can't re-bind closure variables in Python 2. In Python 3, which you appear to be using due to your print()
, you can declare them nonlocal
:
def foo():
counter = 1
def bar():
nonlocal counter
counter += 1
print("bar", counter)
return bar
bar = foo()
bar()
Otherwise, the assignment within bar()
makes the variable local, and since you haven't assigned a value to the variable in the local scope, trying to access it is an error.
In Python 2, my favorite workaround looks like this:
def foo():
class nonlocal:
counter = 1
def bar():
nonlocal.counter += 1
print("bar", nonlocal.counter)
return bar
bar = foo()
bar()
This works because mutating a mutable object doesn't require changing what the variable name points to. In this case, nonlocal
is the closure variable and it is never reassigned; only its contents are changed. Other workarounds use lists or dictionaries.
Or you could use a class for the whole thing, as @naomik suggests in a comment. Define __call__()
to make the instance callable.
class Foo(object):
def __init__(self, counter=1):
self.counter = counter
def __call__(self):
self.counter += 1
print("bar", self.counter)
bar = Foo()
bar()
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…