我在这里做错了什么?Python中的UnboundLocalError
counter = 0
def increment():
counter += 1
increment()
上面的代码会抛出一个UnboundLocalError
。
我在这里做错了什么?Python中的UnboundLocalError
counter = 0
def increment():
counter += 1
increment()
上面的代码会抛出一个UnboundLocalError
。
Python没有变量声明,所以它必须弄清楚的变量本身scope。它是通过一个简单的规则来实现的:如果函数内部有一个变量赋值,该变量被认为是本地的。 [1]因此,线
counter += 1
隐含使得counter
本地increment()
。尽管如此,尝试执行此行将在分配之前尝试读取本地变量counter
的值,从而产生UnboundLocalError
。 [2]
如果counter
是一个全局变量,该global
关键字会有所帮助。如果increment()
是本地函数,并且counter
是本地变量,则可以在Python 3.x中使用nonlocal
。
python 3 docs has a [faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value](https://docs.python.org/3/faq/programming .html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value)通过[unboundlocalerror-local-variable-l-referenced-before-assignment-python](http:// stackoverflow.com/questions/21456739/unboundlocalerror-local-variable-l-referenced-before-assignment-python) – here 2014-05-04 07:19:41
一个注意到了我,我有一个变量声明在文件的顶部,我可以读取一个函数没有问题,但是要写入我已经在文件顶部声明的变量,我必须使用全局变量。 – mouckatron 2018-02-06 14:35:46
要修改函数内的全局变量,必须使用全局关键字。
当您尝试这样做没有行
global counter
增量的定义内,局部变量命名的计数器产生,从而让你从打乱计数器变量,整个程序可能取决于。
请注意,您只需要在修改变量时使用全局;你可以在增量内读取计数器而不需要全局声明。
您需要使用global statement让你修改的全局变量计数器,而不是一个局部变量:
counter = 0
def increment():
global counter
counter += 1
increment()
如果counter
在规定的封闭范围是不是全球范围内,关于Python 3.x你可以使用nonlocal statement。在关于Python 2.x中相同的情况下,你就没有办法重新分配到外地名counter
,所以你需要做counter
可变和修改:
counter = [0]
def increment():
counter[0] += 1
increment()
print counter[0] # prints '1'
酷..它工作+1 – 2016-10-06 06:26:52
它的工作表示感谢。 – 2016-11-22 09:05:15
试试这个
counter = 0
def increment():
global counter
counter += 1
increment()
Python在默认情况下具有词法作用域,这意味着虽然封闭作用域可以访问其封闭作用域中的值,但它不能修改它们(除非它们是用关键字global
声明为全局的)。
的封盖结合在值封闭环境的名称在当地环境。然后本地环境可以使用绑定值,甚至可以将该名称重新分配给其他名称,但不能修改封闭环境中的绑定。
在你的情况下,你试图把counter
当作局部变量而不是绑定值。请注意,此代码,结合在封闭的环境中分配的x
值,正常工作:
>>> x = 1
>>> def f():
>>> return x
>>> f()
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)
@ZeroPiraeus:你为什么锤问题与40K +的看法,这是“UnboundLocalError”的第一个结果在谷歌,作为一个几乎相同的新问题,你回答的副本,而不是简单地发布你的答案*在这里*? – vaultah 2017-01-03 00:26:05
这个问题和它目前标记为重复的问题正在[Python聊天室](http://chat.stackoverflow.com/transcript/message/34899645#34899645)中讨论。 – 2017-01-03 01:30:44
这里的许多答案都表示使用'global',尽管有效,但在其他选项存在的情况下,通常不推荐使用可修改的全局变量。 – 2017-01-03 01:34:48