通过在函数体中的某处添加赋值语句来修改以前工作的代码中的UnboundLocalError会令人感到意外。

这段代码:

>>> x = 10
>>> def bar():
...     print(x)
>>> bar()
10
工作,但这段代码:
>>> x = 10
>>> def foo():
...     print(x)
...     x += 1

导致UnboundLocalError:

>>> foo() 
Traceback (most recent call last): 
... 
UnboundLocalError: local variable 'x' referenced before assignment

这是因为当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并在外部作用域中隐藏任何类似命名的变量。由于foo中的最后一个语句为其分配了一个新值 x,编译器会将其识别为局部变量。因此,当先前print(x)尝试打印未初始化的局部变量并导致错误时。

在上面的示例中,您可以通过将其声明为全局来访问外部范围变量:

>>> x = 10 
>>> def foobar(): 
... global x 
... print(x) 
... x += 1 
>>> foobar() 
10

这个显式声明是必需的,以便提醒您(与类和实例变量的表面类似情况不同),您实际上是在外部作用域中修改变量的值:

>>> print(x) 
11

您可以使用nonlocal 关键字在嵌套范围内执行类似的操作:

>>> def foo(): 
...     x = 10 
...         def bar(): 
...             nonlocal x 
...             print(x) 
...             x += 1 
...         bar() 
...         print(x) 
>>> foo() 
10 
11