我们都知道,在python编程中,对变量的引用遵循LEGB规则。对一个变量的引用,其先会在本地命名空间中去寻找这个变量的引用,如果没有,则依次根据LEGB的顺序去寻找引用。
本文要讲的陷进在于,我们有时候会期望一个非本地变量直接作用在本地,但是在本地引用之后又将该变量声明为本地变量,这时就会报错,因为本地变量在声明之前就被引用了。这里的陷进之处就是无意的将变量声明为了本地变量,这个无意之举往往就是赋值语句。参考如下代码。
def f1(number):
def f2():
if number>0:
number -= 1
print(number)
else:
print(number)
f2()
def f3(number):
def f4():
nonlocal number
if number>0:
number -= 1
print(number)
else:
print(number)
f4()
上面的f1中,number -= 1语句将number变量声明为了本地变量,但是之前又在if语句中引用了number,所以直接调用f1会报错:UnboundLocalError: local variable 'number' referenced before assignment。这时,如果不想另行修改代码,我们可以像f3一样,直接在f4中,先把number声明为nonlocal,这样对number的引用就会跳过本地命名空间的搜索,直接从E处开始,这正是我们预期的,从而不会报错。