zoukankan      html  css  js  c++  java
  • python变量和作用域

    1、作用域介绍 
    python中的作用域分4种情况: L:local,局部作用域,即函数中定义的变量;
    E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
    G:globa,全局变量,就是模块级别定义的变量; B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

    1
    2
    3
    4
    5
    6
    7
    x = int(2.9)  # int built-in
     
    g_count = 0  # global
    def outer():
        o_count = 1  # enclosing
        def inner():
            i_count = 2  # local

    当然,local和enclosing是相对的,enclosing变量相对上层来说也是local。 
    2、作用域产生 
    Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码:

    1
    2
    3
    4
    if True:
        x = 1;
    print(x)
    # 1

    这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用。

    1
    2
    3
    4
    def test():
        x2 = 2
    print(x2)
    # NameError: name 'x2' is not defined

    def、class、lambda是可以引入新作用域的。 
    3、变量的修改 
    一个不在局部作用域里的变量默认是只读的,如果试图为其绑定一个新的值,python认为是在当前的局部作用域里创建一个新的变量,也就是说在当前局部作用域中,如果直接使用外部作用域的变量,那么这个变量是只读的,不能修改,如:

    1
    2
    3
    4
    5
    6
    7
    count = 10
    def outer():
        print(count) 
        count = 100
        print(count)
    outer()
    #UnboundLocalError: local variable 'count' referenced before assignment


    这里第一个print中,使用到了外部作用域的count,这样后面count就指外部作用域中的count了,再修改就会报错。 如果没使用过这个变量,而直接赋值,会认为是新定义的变量,此时会覆盖外部作用域中变量,如:

    1
    2
    3
    4
    5
    6
    count = 10
    def outer():
        count = 100  
        print(count)
    outer()
    #100

    内部作用域中直接声明了count=100,后面使用count都是内部作用域的了。 
    4、global关键字 
    当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    count = 10
    def outer():
        global count
        print(count) 
        count = 100
        print(count)
    outer()
    #10
    #100


    5、nonlocal关键字 
    global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def outer():
        count = 10
        def inner():
            nonlocal count
            count = 20
            print(count)
        inner()
        print(count)
    outer()
    #20
    #20



    6、小结 
    (1)变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域; (2)只有模块、类、及函数才能引入新作用域; (3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量; (4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个关键字,就能完美的实现闭包了。

  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/encode/p/4575077.html
Copyright © 2011-2022 走看看