导航

nonlocal和global

Posted on 2019-03-25 23:17  菜花教授  阅读(134)  评论(0编辑  收藏  举报

获取变量时遵循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的局部变量