zoukankan      html  css  js  c++  java
  • Python3 函数作用域

    一 LEGB

    什么是LEGB?

    L:local 函数内部作用域
    E:enclosing 函数内部与内嵌函数之间
    G:global 全局作用域
    B:build-in 内置作用域

    顺序是什么?

    跟名字一样,Python在函数里面的查找分为4种,称之为LEGB,也正是按照这种顺序来查找的。

    首先,是local,先查找函数内部
    然后,是enclosing,再查找函数内部与嵌入函数之间(是指在函数内部再次定义一个函数)
    其次,是global,查找全局
    最后,是build-in,内置作用域

    实例(Python3.0+):

    name = 'wangyw'
    
    def foo():
        name = 'maoj'
        def bar():
            print(name)  # 打印的name时就用到函数作用域,它会找本函数中是否存在此变量,如不存在找上级函数中是否存在,逐级上寻找变量,直到找到变量位置。
        return bar
    
    foo()
    a = foo() # 把执行foo()函数得到的return返回值赋值给a,也就是把返回值bar赋值给a
    print(a)  # 此时打印的是a(bar)的内存地址
    a() # 相当于执行bar()

    二 函数变量

    我们通常把定义在函数外的变量成为全局变量,定义在函数内的变量称为局部变量,顾名思义,全局变量的作用域是整个代码段,局部变量的作用域就只是在它所属的代码段,变量只在它的作用域里有效。 

    通过实例,我们可以进一步理解下,全局和局部的概念。

    实例1(Python3.0+):

    count = 10  # 全局变量
    
    def print_local():
        count = 5  # 局部变量,这个count覆盖了全局变量count,这2个是不同的变量。
        print(count)
    
    def print_global():
        print(count)  # 这里的count是最上面的全局变量噢
    
    print_local()
    print_global()
    
    """
    运行结果:
    >> 5
    >> 10
    """
    

    global

    • 函数中引用修改全局变量

    实例(Python3.0+):

    count = 10
    def foo():
        global count # 告知程序count是全局变量
        print(count)
        count = 7   # 修改全局变量count的值
        print(count)
    
    foo()
    
    """
    运行结果:
    >> 10
    >> 7
    """
    

    nonlocal

    • 引用修改父级局部变量

    实例(Python3.0+):

    count = 100
    
    def foo():
        count = 10
        
        def inter():
            nonlocal count
            # 引用父级局部变量
            print(count)
            count = 20
            print(count)
        inter()
        print(count)
        
    foo()
    
    """
    运行结果:
    >> 10
    >> 20
    >> 20
    """

    小结:

    • 变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>Python内置作用域。
    • 只有模块、类以及函数才能引用新作用域。
    • 对于一个变量,内部作用域声明会覆盖外部变量,不直接声明,就会使用外部作用域的变量。
    • 内部作用域要修改外部作用域变量的值时,全局变量要使用golbal关键字,嵌套作用域变量要使用nonlocal关键字,nonlocal是Python3新增的关键字,有了这个关键字,就能完美的实现闭包了。
    • 如果函数的内容中无global关键字,优先读取局部变量;如无局部变量,则读取全局变量,但无法对全局变量进行重新赋值(name="ffff"),对于可变类型(列表,字典),可以对内部元素进行操作。

    错误实例1:

    name = "lvcm"
    
    def count():
        print(name)
        name = "wangyw"
        print(name)
    
    count()
    
    """
    运行结果:
    >> UnboundLocalError: local variable 'name' referenced before assignment
    """

    错误实例1,函数中没有使用global关键字,print(name),读取的是全局变量name,不能对全局变量name进行修改,但如果name是可变类型(字典,列表)时,可以对全局变量进行修改操作。

    实例:

    name = ['zhubj','age']
    
    def count():
        print(name)
        name.append("wangyw")
        # 列表的所有方法都可以使用
        print(name)
    
    count()
    print(name)
                
    
    """
    运行结果:
    >>> ['zhubj', 'age']
    >>> ['zhubj', 'age', 'wangyw']
    >>> ['zhubj', 'age', 'wangyw']
    """

    错误实例2:

    name = ['name','age']
    
    def count():
        name = "wangyw"
        global name
        print(name)
    
    count()
    
    """
    运行结果:
    >>> SyntaxWarning: name 'name' is assigned to before global declaration global name
    
    备注:函数中使用global声明全局变量时,global之前不能定义与全局变量同名的局部变量,否则会报错。为了避免报错,代码中全局变量使用大写,局部变量使用小写
    """
    

     

  • 相关阅读:
    POJ 1325、ZOJ 1364、HDU 1150 Machine Schedule
    约数的计算
    Opencv距离变换distanceTransform应用——细化字符轮廓&&查找物体质心
    霍夫圆变换
    【奇葩笔试】—— printf() 作为函数的参数及其返回值
    【奇葩笔试】—— printf() 作为函数的参数及其返回值
    字典(dictionary)的设计
    字典(dictionary)的设计
    极值点、驻点、鞍点、拐点
    极值点、驻点、鞍点、拐点
  • 原文地址:https://www.cnblogs.com/lvcm/p/9230019.html
Copyright © 2011-2022 走看看