• Python中的global和nonlocal


    在Python中,一个变量的scope范围从小到大分成4部分:Local Scope(也可以看成是当前函数形成的scope),Enclosing Scope(简单来说,就是外层函数形成的scope),Global Scope(就是当前文件形成的scope),Builtins Scope(简单来说,就是Python内置的变量位于最顶层的scope)。当Python开始查找一个非限定的变量名时(像obj.attr中的attr,就是一个被限定的变量名字,它被限定在obj对象中,而普通的变量名就是没有限定的),总是从当前变量名所处的scope开始,顺着前面提到的scope链开始往上查找,一旦查找到就不会往上再继续查找,如果查找完整个scope链还是没找到,Python会报错。

    上面提到的变量名查找顺序,可以简单的记为LEGB(每一个scope的首字母),而global和nonlocal,可以改变查找顺序。

    global

    在文件中声明的变量自动成为global的,而如果想在一个函数里面声明一个全局变量,就需要使用global关键字:

    global var1, var2, ...     # 多个变量用逗号隔开

    对于global关键字,需要注意以下几点:

    1 当Python看到一个变量由global变量声明,开始查找的scope不是从这个变量当前所在的scope开始查找,而是从Global Scope开始查找;如果Global Scope没有找到,就会继续到Builtins Scope查找;

    2 global关键字声明的对象允许赋值,如果这个变量之前不存在,那么,这次赋值就是创建了一个全局变量;如果这个变量之前存在,那么,这次赋值就改变了这个全局变量的值:

    def test():
        global x
        x = 1    # x之前不存在,因此在Global Scope创建了一个全局变量x
    
    
    
    x = 1
    
    def test():
        global x
        x = 99    # x之前在Global Scope中已经存在,因此这里是改变x的值

    3 只要被global关键字声明的变量,都会成为全局变量,如果该变量原来不是全局变量,也会如此,并且,如果之前Global Scope里面有同名变量,那么被global声明的变量会取代这个同名变量:

    x = 99
    
    def test():
        x = 88
        global x    # 这样做的话Python会产生警告:SyntaxWarning: name 'x' is assigned to before global declaration
    
    >>>print(x)           # 一开始访问的是全局变量x
    >>>99
    >>>test()              # 执行test函数之前,原本函数里面的局部变量x成为了全局变量,并取代原来的全局变量
    >>>print(x)          # 现在访问的是取代后的全局变量x,值变为88
    >>>88
    
    
    
    # 在看一个例子,加入开始没有定义全局变量x
    def test():
        x = 88
        global x    # 仍会产生相同的警告
    
    >>>test()
    >>>print(x)   # 打印结果为88!!!
    >>>88

    nonlocal

    nonlocal是Python 3.X加入进来的关键字,Python 2.X中没有。在Python中,嵌套函数是可以访问外部函数的变量的(至少在>Python 2.2的版本是这样的,在Python 2.2之前的版本中,变量的查找从当前函数开始,然后直接到Global Scope,Builtins Scope,跳过了外层函数),但是却不可以改变外部函数变量的值,如果确实要改变,就的使用nonlocal变量进行声明:

    nonlocal var1, var2,...   # 只在Python 3.X中支持,多个变量用逗号隔开

    对于nonlocal关键字,需要注意以下几点:

    1 nonlocal关键字只在Python 3.X中支持,Python 2.X没有这个关键字;

    2 nonlocal关键字只可以在函数内部使用,在其他地方使用会报错;

    3 nonlocal声明的变量,之前必须已经存在(并且是在外部函数中存在),如果变量不存在就对这个变量赋值,会报错,这点和global关键字不一样:

    # 变量存在于Global Scope
    x = 99
    
    def test():
        nonlocal x           # 报错:SyntaxError: name 'x' is assigned to before nonlocal declaration
    
    
    # 变量存在于当前函数
    def test():
        x = 99
        nonlocal x           # 报错:SyntaxError: name 'x' is assigned to before nonlocal declaration

    4 对于nonlocal声明的变量,只会在外部函数中查找该变量,不会在Global Scope和Builtins Scope中查找

  • 相关阅读:
    mongodb基础系列——数据库查询数据返回前台JSP(一)
    整型数组处理算法(十二)请实现一个函数:最长顺子。[风林火山]
    学习C++服务端一:MySql与C++
    【算法】深度优先搜索(DFS)III
    DOS cmd
    C# wpf程序获取当前程序版本
    Climbing Stairs
    Java深入
    非对称算法,散列(Hash)以及证书的那些事
    省市区镇(能够选四级)联动点击自己主动展开下一级
  • 原文地址:https://www.cnblogs.com/chaoguo1234/p/9218207.html
Copyright © 2020-2023  润新知