• 【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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    10
    
    • 1

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

    a = 10
    def fun2():
        global a
        a = 20
    
    print(a)
    fun2()
    print(a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    10
    20
    
    • 1
    • 2

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

    def fun():
        global a
        a = 20
    
    fun()
    print(a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    20
    
    • 1

    nonlocal

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

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

    def fun1():
        a = 10
        def fun2():
            nonlocal a
            a = 20
        fun2()
        print(a)
    
    fun1()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    20
    
    • 1

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

    def fun1():
        a = 10
        def fun2():
            def fun3():
                nonlocal a
                a = 20
            fun3()
        fun2()
        print(a)
    
    fun1()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    20
    
    • 1

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

    a = 10
    def fun1():
        def fun2():
            def fun3():
                nonlocal a
                a = 20
            fun3()
        fun2()
        print(a)
    
    fun1()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    SyntaxError: no binding for nonlocal 'a' found
    
    • 1
  • 相关阅读:
    上海亚商投顾:沪指冲高回落 医药股集体爆发
    为什么我抓不到baidu的数据包
    uniapp使用nfc功能及详解
    Sui流动性质押黑客松获胜者公布,助力资产再流通
    Prompt learning 教学[进阶篇]:简介Prompt框架并给出自然语言处理技术:Few-Shot Prompting、Self-Consistency等;项目实战搭建知识库内容机器人
    安全保护策略:iOS应用程序代码保护的关键步骤和技巧
    vue-组件生命周期+网络请求
    Java中ArrayList和LinkedList区别
    C++核心编程:P18->STL----常用算法(上)
    -完全数-
  • 原文地址:https://blog.csdn.net/atwdy/article/details/126015730