获取变量时遵循LEGB原则,
修改变量时需要global/nonlocal进行修改
global
# global的使用
函数外定义了全局变量: global关键字在函数内会修改全局变量
函数外没定义全局变量: global会在函数内定义全局变量(不管是几层闭包, 只要调用了就会定义)
nonlocal
1.修改当前作用域上一级(局部变量) 2.如果上一级也没有, 就继续向上 3.再找不到, 就会报错(不会到全局变量中寻找)
1 def outer(): 2 a = 1 3 def inner(): 4 # nonlocal a 5 a += 5 6 7 # UnboundLocalError: local variable 'a' referenced before assignment 8 # 此处为修改操作, 需要用nonlocal声明才可以进行 9 print(a) 10 return inner() 11 12 outer()
可变数据类型不用global声明也可以更改的情况:
1 li = [1, 2, 3] 2 print(li, id(li)) # [1, 2, 3] 2661565497032 3 4 5 def func(): 6 # 修改了li的元素, 但是并没有修改li这个变量所指向的地址 7 li[1] = 55 8 print(li, id(li)) # [1, 55, 3] 2661565497032 9 10 11 func() 12 print(li, id(li)) # [1, 55, 3] 2661565497032
删除局部变量, 不会再向全局中寻找的情况
1 def func(): 2 a = 2 3 del a 4 print(a) 5 6 func() 7 # UnboundLocalError: local variable 'a' referenced before assignment 8 # 函数内的a有标志位, 已经记录删除a变量过后, 不会在向外部寻找a变量
内层函数对全局变量的操作修改还是赋值
1 dic = {'a':1} 2 def func(): 3 # 可以修改dic元素内容 4 dic[1] = 2 5 # 此操作为修改dic变量, 不是赋值dic变量, 6 # 从上到下已经记录定义了dic为全局变量 7 # 需要用到global才可以修改 8 dic = 1 9 10 func() 11 # UnboundLocalError: local variable 'dic' referenced before assignment
注意事项:
1 def func(): 2 a = 10 3 def inner(): 4 nonlocal a 5 a = 5 # 这个是nonloca声明修改外部函数的a变量 6 a = 10 # 这次是给inner函数增加了个a的局部变量