为什么会出现这个UnboundLocalError(闭包)?
我这里做错了什么呢?
counter = 0
def increment():
counter += 1
increment()
上面的代码会报一个叫做 UnboundLocalError
的错误。
8 个回答
30
针对你标题中的问题,* 是的,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中的闭包。
95
你需要使用 global 语句,这样你才能修改全局变量 counter,而不是局部变量:
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'
227
Python没有变量声明,所以它需要自己判断变量的作用域。它是通过一个简单的规则来做到这一点的:如果在一个函数内部给一个变量赋值,那么这个变量就被认为是局部变量。[1] 也就是说,下面这一行
counter += 1
会让counter
被视为increment()
函数中的局部变量。不过,如果你在执行这行代码时,试图在给counter
赋值之前读取它的值,就会出现一个错误,叫做UnboundLocalError
。[2]
如果counter
是一个全局变量,使用global
关键字会有所帮助。如果increment()
是一个局部函数,而counter
是一个局部变量,你可以在Python 3.x中使用nonlocal
。