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

    python中函数作用域

    在python中,一个函数就是一个作用域

    name = 'xiaoyafei'
    
    def change_name():
        name = '肖亚飞'
        print('在change_name里的name:',name)
    
    change_name()  # 调用函数
    print("在外面的name:",name)
    

    运行结果如下:

    在change_name里的name: 肖亚飞
    在外面的name: xiaoyafei
    

    我们再试一下在嵌套函数中是如何的寻找的?

    age = 15
    def func():
        print('第一层age:',age)  # 第一层age: 15
    
        def func2():
            age = 73
            print("func2中的age:",age)  # func2中的age: 73
    
            def func3():
                age = 84
                print("func3中的age:",age)  # func3中的age: 84
    
            func3()  # 调用func3函数
    
        func2()  # 调用func2函数
    
    func()
    

    在以上嵌套函数中,就能够很好的说明一个函数就是一个作用域,那么我们现在稍微改一下代码看看情况?

    age = 15
    def func():
        print('第一层age:',age)  # 第一层age: 15
    
        def func2():
            print("func2中的age:",age)  # func2中的age: 15  # 看到没有,如果当前作用域里没有age变量,那么它就会往上找
    
            def func3():
                age = 84
                print("func3中的age:",age)  # func3中的age: 84
    
            func3()  # 调用func3函数
    
        func2()  # 调用func2函数
    
    func()
    

    那么,这时候有人就说了,屁话一大堆讲的原来是局部变量和全局变量,那么我想问:在上面这个嵌套函数中,func2中并没有age变量,那么它是如何找到全局变量age = 15的?

    此时我们就需要来看一下作用域的查找顺序了:

    变量作用域LEGB

    • L:locals 函数内的名称空间,包括局部变量和实参
    • E:enclosing 外部嵌套函数的名称空间,即相邻的上一层,打个比方说:func2中没有age变量则会去func里找这个
    • G:globals 全局变量
    • B:builtins 内置模块的名称空间

    咳咳,还是先了解下什么是名称空间把?

    名称空间,又名name space,顾名思义就是存放名字的地方,存什么名字呢?举例说明,x = 1 ,1存放在内存当中,那么变量名x存放在哪里呢?名称空间就是存放名字x与1绑定关系的地方

    >>> x = 1
    >>> id(1)
    1576430608
    

    名称空间分为以下3种:

    • locals: 是函数内的名称空间,包括局部变量和形参
    • globals: 全局变量,函数定义所在模块的名字空间
    • builtins: 内置模块的名字空间

    不同变量的作用域不同就是有这个变量所在的命名空间决定的.

    作用域即范围

    • 全局范围:全局存活,全局有效
    • 局部范围:临时存货,局部有效

    让我们来举例看一下

    level = 'L0'
    n = 22
    
    
    def func():
        level = 'L1'
        n = 33
        print(locals())  # {'n': 33, 'level': 'L1'}  在之前说过在python中,一个函数就是一个作用域,这就很完美的体现了
    
        def outer():
            n = 44
            level = 'L2'
            print(locals(),n)  # {'level': 'L2', 'n': 44} 44
    
            def inner():
                level = 'L3'
                print(locals(),n) # {'level': 'L3', 'n': 44} 44
            inner()
        outer()
    
    
    func()
    

    以 L --> E --> G -->B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置函数中找。

  • 相关阅读:
    sql被注入,用友不能建账
    项目总帐金额翻倍
    1)123104科目的余额出现翻倍情况,经调数据库,期初余额已调平,但余额表中的数仍是未调平前的错误数。2)一月结账时提示有一科目119101的总账与个人明细账不平....
    尚有已全部暂估报销的单据未进行处理,不能进行12月的期末处理
    用友U8尚有已全部暂估报销的单据未进行处理,不能进行12月的期末处理
    用sql替换T6工作流中的操作员
    解决win7科迈登录报错RASRDP MODULE已停止工作
    sql2005 64 位 连接 sql2000 32位
    jquery选择器
    深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法
  • 原文地址:https://www.cnblogs.com/xiaoyafei/p/8998933.html
Copyright © 2011-2022 走看看