我哪里做错了?
counter = 0
def increment():
counter += 1
increment()
上面的代码抛出一个UnboundLocalError。
我哪里做错了?
counter = 0
def increment():
counter += 1
increment()
上面的代码抛出一个UnboundLocalError。
当前回答
您的代码抛出UnboundLocalError的原因已经在其他答案中得到了很好的解释。
但在我看来,您正在尝试构建类似itertools.count()的东西。
所以试试吧,看看它是否适合你的情况:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
其他回答
Python不是纯粹的词法作用域。
参见在函数中使用全局变量。
和Python变量作用域注释。
试试这个:
counter = 0
def increment():
global counter
counter += 1
increment()
要回答主题行中的问题,是的,Python中有闭包,只是它们只应用于函数内部,而且(在Python 2.x中)它们是只读的;不能将名称重新绑定到不同的对象(但如果对象是可变的,则可以修改其内容)。在Python 3中。X,您可以使用nonlocal关键字来修改闭包变量。
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
*这个问题最初问的是Python中的闭包。
Python没有变量声明,所以它必须自己找出变量的作用域。它通过一个简单的规则来做到这一点:如果在函数中对某个变量进行了赋值,则该变量被认为是局部的。[1]因此,直线
counter += 1
隐式地将increment()的计数器设为本地。但是,尝试执行这一行将尝试在分配局部变量counter之前读取它的值,从而导致UnboundLocalError.[2]
如果counter是一个全局变量,则global关键字将有所帮助。如果increment()是一个局部函数,而计数器是一个局部变量,则可以在Python 3.x中使用nonlocal。
Python默认具有词法作用域,这意味着尽管封闭作用域可以访问其封闭作用域中的值,但它不能修改它们(除非它们用global关键字声明为全局)。
闭包将封闭环境中的值绑定到本地环境中的名称。然后,本地环境可以使用绑定值,甚至将该名称重新分配给其他名称,但不能修改封闭环境中的绑定。
在您的情况下,您试图将counter视为局部变量而不是绑定值。注意,这段代码绑定了在封闭环境中赋值的x,工作正常:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1