nonlocal的作用:
嵌套函数变量引用问题
nonlocal的作用:
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
首先我们要清楚:变量引用的规则
函数内部嵌套函数时,最内层的函数引用某一个变量时(x),先在本层函数中寻找有没有之前对该变量(x)的定义,如果有直接引用,如果没有则会在该层函数的上一层中寻找。如果还没有就依次向上层寻找。
当弄清了上面所述的,我们来看下面的四个程序test1、test1_a、test1_b、test1_c
名称 | test1 |
test1_a | test1_b |
test1_c |
代 码 |
def func():
func() |
def func(): x = 200
func()
|
def func(): |
def func(): func() |
执行 结果 |
200 | 报错 UnboundLocalError: local variable 'x' referenced before assignment |
200 | 200 |
test1

def func(): x = 200 def func2(): print(x) func2() func()test1
test1_a

def func(): x = 200 def func2(): x=x print(x) func2() func()test1_a
test1_b

def func(): x = 200 def func2(): nonlocal x x=x print(x) func2() func()test1_b
test1_c

def func(): x = 200 def func2(): y=x print(y) func2() func()test1_c
首先test1程序的结果验证了我们上述的变量引用规则,func2中的语句print(x)对变量x进行打印,由于本层函数func2中没有定义x所以在func2的上层寻找,找到了func中的x=200,于是func打印的x值为200。
我们再来看test1_a这个程序,内层函数func2中有一个语句x=x,第一个x是变量的定义(这时说明本层函数定义了一个变量x),第二个x就需要寻找引用值了,现在本层函数中寻找,这就找到了刚刚定义的变量x,也就时第一个x。相当与定义后面承接着引用,这就会产生一个问题:变量x实际上是没有值的,所以程序会报错。
而test1_b中内层函数func2在执行x=x语句时,用nonlocal x这个语句声明了x引用的范围(跳过本层的引用),也就在后面执行x=x这一语句时,第二个x不再引用第一个x,跳过了本层的引用,引用了上一层的 x = 200,再把这个x赋给本层定义的x,最后程序的结果就是200
我们再来通过test1_a和test1_c来对比分析,可以看到test1_c中内层函数func2中定义的变量换成了y,这就使得后面的x在引用时由于在本层找不到定义的x,所以就接着到上层寻找。
而test1_b和test1_c比较可以发现,在遇到嵌套函数变量引用的问题时,除了通过使用nonlocal x 语句使得x跳过本层寻找外,还可以通过跟换本层定义的变量名,使得x再寻找引用时由于本层没有对x的定义而跳至上层寻找。
