我在这里做错了什么?
counter = 0
def increment():
counter += 1
increment()
上面的代码会抛出一个UnboundLocalError
异常。
我在这里做错了什么?
counter = 0
def increment():
counter += 1
increment()
上面的代码会抛出一个UnboundLocalError
异常。
,然后
from copy import deepcopy; foo()。如果删除本地导入
from copy import deepcopy`,则调用将成功。 - Yibo Yang您需要使用global语句,以便修改全局变量计数器,而不是本地变量:
counter = 0
def increment():
global counter
counter += 1
increment()
如果定义 counter
的封闭作用域不是全局作用域,那么在Python 3.x中可以使用nonlocal语句。 在Python 2.x中,在同样的情况下,您将无法重新分配非本地名称counter
,因此您需要使counter
可变并对其进行修改:
counter = [0]
def increment():
counter[0] += 1
increment()
print counter[0] # prints '1'
回答您标题中的问题,是的,在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中闭包的。
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具有默认的词法作用域,这意味着尽管封闭作用域可以访问其封闭作用域中的值,但它不能修改它们(除非使用global
关键字声明为全局变量)。
闭包将封闭环境中的值绑定到本地环境中的名称。然后,本地环境可以使用绑定的值,甚至重新分配该名称以指向其他内容,但它无法修改封闭环境中的绑定。
在您的情况下,您试图将counter
视为本地变量而不是绑定值。请注意,此代码绑定了在封闭环境中分配的x
的值,可以正常工作:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
global counter
试试这个:
counter = 0
def increment():
global counter
counter += 1
increment()
global
,虽然这种方法可以解决问题,但通常不建议使用可修改的全局变量,除非没有其他更好的选择。 - PM 2Ring