• Python作用域


    Python是静态作用域,也就是说在Python中,变量的作用域源于它在代码中的位置。与C语言有一些类似,与C语言比起来还有一些需要注意的地方。

    现在的Python支持4种作用域,"LEGB"

    • L(local):局部作用域;
    • E(Enclosing): 闭包函数外的函数中;
    • G(Global):全局作用域;
    • B(Build-in):內建作用域;

    在Python中只有模块函数会引入新的作用域,其他代码是不会引入新的作用域的
    看下列C代码和Python代码

    // C code
    #include <stdio.h>
    int main(){
        if(2>0)
            int i = 0
        printf("i = %d", i);
        return
    }
    
    # Python code
    if True:
        i = 0
    print(i)
    

    上述代码中C代码编译会失败,而Python代码将成功运行。在上述Python代码中,if语句并没有引入一个新的作用域,变量i存在于全局作用域中,所以变量i对于接下来的print语句将是可见的。

    在Python中使用一个变量之前不需要先对其进行声明,但真正使用它之前,这个变量必须被绑定到某个对象上,而且名字绑定将在当前作用域中引入新变量,同时屏蔽外层作用域的同名变量,不论这个名字绑定发生在当前作用域中的哪个位置。(下面代码 code3会体现)

    # code 1
    def f():
        print(i)
    f()
    # 运行结果 ==> NameError: global name 'i' is not defined
    
    # code 2
    i = 0
    def f():
        i = 8
        print(i)
    f()
    print i
    # 运行结果 ==>  8 和 0
    
    # code 3
    i = 0
    def f():
        print(i)
        i = 0
    f()
    
    # 运行结果 ==> UnboundLocalError: local variable 'i' referenced before assignment
    
    # code 4
    print(i)
    i = 0
    # 运行结果 ==> NameError: name 'i' is not defined
    
    • Python查找变量按照L->E->G->B的顺序的规则查找,在code 1中,在函数作用域中和全局作用域找不到i变量,所以报出global name not define
    • 由于函数作用域会屏蔽全局作用域,所以输出结果是8 和 0 而不是 8 和 8
    • code 3中显示的是UNboundLocalError (这是什么鬼>_>),另外code 4中无论是以交互方式运行还是脚本方式运行,都是显示NameError。综合这两个错误我们可以总结如下的结论。对函数体而言,Python在运行之前会对代码进行预处理,因此无论名称绑定发生在作用域的哪个地方,它都能感知出来,并且屏蔽全局作用域,但是对象绑定却是动态发生的,所以在code3处出现的是UNboundLocalError, 因为运行到 print(i)时 变量i仍未绑定到实际对象上。但是对于顶级作用域(模块作用域),却没有做任何预处理,所以出现的是name 'i' is not defined的错误。
  • 相关阅读:
    js 判断用户是否联网
    vue cli 2.9.6 低版本安装失败
    'webpack-dev-server' 不是内部或外部命令,也不是可运行 的程序 或批处理文件。
    Jenkins创建运行用例
    python的类变量和成员变量
    Airtest移动端自动化测试环境搭建 一
    pytest使用总结笔记
    Python单元测试框架之pytest---如何执行测试用例
    UI自动化之分层思想pom模式
    【Fiddler篇】抓包工具之Filters(过滤器)进行会话过滤
  • 原文地址:https://www.cnblogs.com/pluviophile/p/7441711.html
Copyright © 2020-2023  润新知