nonlocal和global

获取变量时遵循LEGB原则,
修改变量时需要global/nonlocal进行修改

global

# global的使用
函数外定义了全局变量: global关键字在函数内会修改全局变量

函数外没定义全局变量: global会在函数内定义全局变量(不管是几层闭包, 只要调用了就会定义)

nonlocal

1.修改当前作用域上一级(局部变量)
2.如果上一级也没有, 就继续向上
3.再找不到, 就会报错(不会到全局变量中寻找)
def outer():
    a = 1
    def inner():
        # nonlocal a
        a += 5
        
        # UnboundLocalError: local variable 'a' referenced before assignment
        # 此处为修改操作, 需要用nonlocal声明才可以进行
        print(a)
    return inner()

outer()

可变数据类型不用global声明也可以更改的情况:

li = [1, 2, 3]
print(li, id(li))       # [1, 2, 3] 2661565497032


def func():
    # 修改了li的元素, 但是并没有修改li这个变量所指向的地址
    li[1] = 55
    print(li, id(li))       # [1, 55, 3] 2661565497032


func()
print(li, id(li))           # [1, 55, 3] 2661565497032

删除局部变量, 不会再向全局中寻找的情况

def func():
    a = 2
    del a
    print(a)

func()
# UnboundLocalError: local variable 'a' referenced before assignment
# 函数内的a有标志位, 已经记录删除a变量过后, 不会在向外部寻找a变量

内层函数对全局变量的操作修改还是赋值

dic = {'a':1}
def func():
    # 可以修改dic元素内容
    dic[1] = 2
    # 此操作为修改dic变量, 不是赋值dic变量, 
    # 从上到下已经记录定义了dic为全局变量
    # 需要用到global才可以修改
    dic = 1

func()
# UnboundLocalError: local variable 'dic' referenced before assignment

注意事项:

def func():
    a = 10
    def inner():
    nonlocal a 
    a = 5    # 这个是nonloca声明修改外部函数的a变量
    a = 10    # 这次是给inner函数增加了个a的局部变量

你可能感兴趣的:(nonlocal和global)