(1)下面这种情况是不会报错的:
>>> x = 10
>>> def bar():
... print(x)
>>> bar()
10
(2)但是这种情况就会报UnboundLocalError的错误:
>>> x = 10
>>> def foo():
... print(x)
... x += 1
该代码会提示UnboundLocalError: local variable ‘x’ referenced before assignment。
Python FAQ给出的回答是:
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.
即如果给一个变量分配一个值,则这个变量会被认为属于当前的代码块,会屏蔽外部代码块(全局)的相同名字的变量。因为(2)中的代码中x+=1,相当于给x分配了一个值,则编译器意识到x是一个局部变量,因为x在print后面被赋值,则在之前调用的print(x)试图访问一个未被初始化的局部变量而失败。
(3)解决方法:将变量声明为global的
>>> x = 10
>>> def foobar():
... **global x**
... print(x)
... x += 1
>>> foobar()
10
(4)在嵌套的代码块中用nonlocal 关键字
>>> def foo():
... x = 10
... def bar():
... global x #nonlocal x
... print(x)
... x += 1
... bar()
... print(x)
>>> foo()
NameError: name 'x' is not defined
这是因为在全局的区域没有定义x变量,x仅仅出现在上一级区域中,因此可以用nonlocal来替换掉global,则x是上一级区域的变量。