【python】变量作用域&LEGB规则&global/nonlocal关键字

文档地址:https://docs.python.org/zh-cn/3.6/tutorial/classes.html#python-scopes-and-namespaces

LEGB

python中的变量查找顺序是按照LEGB规则进行查找的,由内往外逐层查找,找到后就不再往后查找,
L:Local,局部作用域,函数内部的作用域
E:Enclosed,局部作用域与全局作用域之间的作用域,例如函数嵌套中的外层函数的作用域
G:Global,全局作用域,所有函数外部的作用域,与模块同层级
B:Built in,内置变量的作用域

global

global用于声明一个非全局变量为全局变量,全局变量在函数内部只可引用不能修改,如果修改也就是出现"="赋值运算,则相当于在函数内部新建了一个与全局变量同名的局部变量,此时引用必须在定义之后,否则会找不到改局部变量而报错。

比如下面这段代码:

a = 10
def fun1():
    print(a)
    a = 20

def fun2():
    a = 20
    print(a)

fun1()
fun2()

fun2正常,fun1报错"UnboundLocalError: local variable ‘a’ referenced before assignment",原因是fun1和fun2中a=20相当于声明了一个局部变量,而fun1中先引用后声明所以才会出现上面的错误。

因为fun2中是新建的局部变量,所以说赋值操作不会影响全局变量a的值,a还是等于10,

a = 10
def fun2():
    a = 20

fun2()
print(a)
10

如果需要fun2中引用的a是全局变量a,可以使用global关键字在函数内部声明一下,

a = 10
def fun2():
    global a
    a = 20

print(a)
fun2()
print(a)
10
20

global关键字在函数内部声明变量的时候,这个变量可以在全局作用域中未定义,此时相当于在函数内部新建了一个全局变量,

def fun():
    global a
    a = 20

fun()
print(a)
20

nonlocal

nonlocal关键字用于在局部作用域里面引入Enclosed作用域里面的变量(该作用域里离自己最近的那个同名变量),被nonlocal修饰的变量要求在Enclosed作用域中必须存在,否则报错。在局部作用域里对经nonlocal修饰的变量进行修改删除等操作,操作的都是外层Enclosed作用域中的变量。

下面是局部作用域中修改nonlocal修饰的变量,

def fun1():
    a = 10
    def fun2():
        nonlocal a
        a = 20
    fun2()
    print(a)

fun1()
20

nonlocal修饰的变量在Enclosed作用域之间必须存在,可以越级,系统会从Enclosed作用域中由内往外,引入离局部作用域最近的那个同名变量,

def fun1():
    a = 10
    def fun2():
        def fun3():
            nonlocal a
            a = 20
        fun3()
    fun2()
    print(a)

fun1()
20

如果变量a在Enclosed作用域中不存在,比如说把a调换到全局作用于当中,就会报错,

a = 10
def fun1():
    def fun2():
        def fun3():
            nonlocal a
            a = 20
        fun3()
    fun2()
    print(a)

fun1()
SyntaxError: no binding for nonlocal 'a' found

猜你喜欢

转载自blog.csdn.net/atwdy/article/details/126015730