• 您不知道的Python中global、nonlocal哪些事儿


    Python中全局变量、局部变量以及global、nonlocal关键字的用法

    1.全局变量和局部变量

    前言:

    • 全局变量是在整个py文件中声明,全局范围内都可以访问;
    • 局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了
    • 如果在函数内部定义与某个全局变量一样名称的局部变量,就可能会导致意外的效果,可能不是你期望的。因此不建议这样使用,这样会使得程序很不健全。

    有 4 条法则,来区分一个变量是处于局部作用域还是全局作用域:

    1. 如果变量在全局作用域中使用(即在所用函数之外),它就总是全局变量。
    2. 如果在一个函数中,有针对该变量的 global 语句,它就是全局变量。
    3. 否则,如果该变量用于函数中的赋值语句,它就是局部变量。
    4. 但是,如果该变量没用用在赋值语句中,它就是全局变量。

    阅读 例1,可以更好地理解这些法则,

    # 例 1
    def test1():
        global str1
        str1 = 'hello' # 这是全局变量
    def test2():
        str1 = 'python' # 这是局部变量
    def test3():
        print(str1) # 这是全局变量
    str1 = 42   # 这是全局变量
    test1()
    print(str1) # out: hello
    

    解释:在 test1() 函数中,str1 是全局 str1 变量,因为在函数的开始处,有针对 str1 变量的 global 语句。在 test2() 函数中,str1 是局部变量,因为在该函数中有针对它的赋值语句。在 test3() 函数中,str1 是全局变量,因为在这个函数中,既没有赋值语句,也没有针对它的 global 语句。

    • 在一个函数中,一个变量要么总是局部变量,要么总是全局变量。函数中的代码没有办法先使用名为 str1 的局部变量,稍后又在同一个函数中使用全局变量。
    • 如果想在一个函数中修改全局变量中存储的值,就必须对该变量使用 global 语句。
    • 在一个函数中,如果试图在局部变量赋值之前就使用它,Python就会报错。如例2
    #例 2
    def test1():
    	print(str1) # ERROR
    	str1 = 'hello world' # 局部变量
    str1 = 'hi' # 全局变量
    test1()
    '''
    报错:
    File "E:/test/test.py", line 92, in test1
        print(str1) # ERROR
    UnboundLocalError: local variable 'str1' referenced before assignment
    '''
    

    例2解释:之所以报错,因为 Python 看到 test1() 函数中有针对 str1 的赋值语句,所以会认为 str1 变量是局部变量。但是 print(str1) 语句的执行在 str1 赋值之前,局部变量 str1 并不存在(即赋值之前应用本地变量 str1)。Python不会退回使用全局 str1 变量。

    2. global语句

    使用 global 语句可以在一个函数内修改全局变量。如果在函数内的顶部有 " global str1 "这样的代码,它就告诉 Python ,“在这个函数中,str1 指的是全局变量,所以不要用这个名字创建一个局部变量”。例如下面代码:

    def test1():
    	global str1
    	str1 = 'one'
    str1 = 'global'
    test1()
    print(str1) # out: one
    

    因为 str1 在 test1() 的顶部被声明 gloabl,所以当 str1 被赋值为 ‘one’ 时,赋值发生在全局作用域的 str1 上。没有创建局部 str1 变量。

    3. nonlocal语句

    Python 3.0 引入了一条新的nonlocal语句,实际上,当执行到 nonlocal 语句的时候,nonlocal中列出的名称必须在一个嵌套的def中提前定义过,否则,将会产生一个错误。nonlocal名称只能出现在嵌套的def中,而不能在模块的全局作用域中或def之外的内置作用域中。
    表示在局部作用域中,调用父级作用域中的变量;如果嵌套了很多层,最多只能作用到最顶层的函数,不能作用于全局变量。
    在这里插入图片描述
    在这里插入图片描述
    动手算算这些题,理论要和实际相结合

    a = 1
    def func_1():
        a =2
        def func_2():
            # a = 3  #模块A
            def func_3():
                nonlocal a
                a = 4
                print(' 8行:',a)
            print(' 9行:',a)
            func_3()
            print('11行:',a)#2 --> 4
        print('12行:',a)
        func_2()
        print('14行:',a)#2-->4
    print('15行:',a)
    func_1()
    print('17行:',a)#全局变量,nonlocal无权更改
    

    上面代码中,加上模块A的结果:
    在这里插入图片描述
    不加模块A的结果:
    在这里插入图片描述

  • 相关阅读:
    java学习(19-IO高级)
    java学习(18-异常)
    java学习(17-Map和Set)
    java学习笔记(16-集合)
    java学习笔记(15-高级api)
    java学习笔记(14-包和权限修饰符)
    Deno文件处理详解:如何写入文件、如何读文件、如何创建删除以及检查文件和目录。
    2020年12月8日建站随笔:IPlayIO中文网从上线到现在的一些总结
    2020 FreeBSD如何更换国内仓库源
    推荐11个值得研究学习的Python开源项目(从入门到python高级开发)
  • 原文地址:https://www.cnblogs.com/oito/p/12149499.html
Copyright © 2020-2023  润新知