Don't understand why UnboundLocalError occurs
我在这里做错什么了?
1 2 3 4 5 6 | counter = 0 def increment(): counter += 1 increment() |
上面的代码抛出了一个
python没有变量声明,因此必须确定变量本身的范围。它是通过一个简单的规则来实现的:如果在一个函数中有一个变量的赋值,那么这个变量就被认为是局部变量。
1 | counter += 1 |
隐含地使
如果
您需要使用global语句来修改全局变量计数器,而不是局部变量:
1 2 3 4 5 6 7 | counter = 0 def increment(): global counter counter += 1 increment() |
如果
1 2 3 4 5 6 7 | counter = [0] def increment(): counter[0] += 1 increment() print counter[0] # prints '1' |
要回答主题行中的问题,*是的,python中有闭包,但它们只应用于函数内部,而且(在python 2.x中)它们是只读的;不能将名称重新绑定到其他对象(尽管如果对象是可变的,则可以修改其内容)。在python 3.x中,可以使用
1 2 3 4 5 6 7 8 9 10 11 12 | def incrementer(): counter = 0 def increment(): nonlocal counter counter += 1 return counter return increment increment = incrementer() increment() # 1 increment() # 2 |
*最初问题的标题是关于Python中的闭包。
您的代码为什么抛出一个
但在我看来,你是在试图建立一个类似于
所以你为什么不试试看它是否适合你的情况:
1 2 3 4 5 6 7 8 9 10 11 12 | >>> from itertools import count >>> counter = count(0) >>> counter count(0) >>> next(counter) 0 >>> counter count(1) >>> next(counter) 1 >>> counter count(2) |
默认情况下,python具有词法作用域,这意味着尽管封闭作用域可以访问其封闭作用域中的值,但它不能修改这些值(除非使用
闭包将封闭环境中的值绑定到本地环境中的名称。然后,本地环境可以使用绑定值,甚至可以将该名称重新分配给其他名称,但它不能修改封闭环境中的绑定。
在您的案例中,您试图将
1 2 3 4 5 6 7 | >>> x = 1 >>> def f(): >>> return x >>> f() 1 |
要修改函数内的全局变量,必须使用global关键字。
当你试着不打电话的时候
1 | global counter |
在增量定义的内部,会创建一个名为counter的局部变量,以防止您弄乱整个程序可能依赖的计数器变量。
注意,只有在修改变量时才需要使用global;您可以从increment中读取counter,而不需要使用global语句。
试试这个
1 2 3 4 5 6 7 | counter = 0 def increment(): global counter counter += 1 increment() |
python不是纯词汇范围的。
请参见:在创建全局变量的函数之外的函数中使用全局变量
以下是:http://www.saltycrane.com/blog/2008/01/python-variable-scope-notes/