• Python的命名空间namepaces


    1、名称空间(namepaces)与作用域。
      名称空间即存放名字与对象映射/绑定关系的地方。对于x=3,Python会申请内存空间存放对象3,然后将名字x与3的绑定关系存放于名称空间中。
      
      del x表示清除该绑定关系
      
      名称空间:是一个非常重要的思想,不是真正的空间,只是虚拟出来的一块空间,
      作用是:在不同的空间内存放相同是名字,例如:一班有个同学叫张三,男。二班也有同学叫张三,女。
      命名空间分为三类:
        (1)内置名称空间
        (2)全局名称空间
        (3)局部名称空间

         (1)三种名称空间用途与存活周期(这里的活动周期是指python运行程序的三个阶段:启动python解释器,加载文件内容到内存,python执行程序)

     一、名称空间namespace:用于存放名字的地方,是对栈区的划分。
        有了名称空间之后,就可以在栈区中存放相同的名字,
        详细的名称空间分为三种:
        1、内置名称空间:有一个
            存放的名字:存放的是python解释器内置的名字,
            举例如下:
            >>> print
            <built-in function print>
            >>> input
            <built-in function input>
            存活周期:关于python运行程序的三个阶段
                开始:python解释器启动。
                结束:python解释器关闭。
        2、全局名称空间:有一个
            存放的名字:运行顶级代码所产生的名字,只要不是函数内定义的和内置的,全为全局名称空间。
                顶级:在python解释器里:没有缩进的叫顶级
                例如:
                示例一:import os
                示例二: x = 10
                示例三:这里的y和z都是全局命名空间
                    if 13 > 3:
                        y = 20
                        if 3 == 3:
                            z=30
                示例四:func=函数的内存地址,是全局命名空间,a和b数据局部命名空间
                    def func():
                        a=111
                        b=222
            存活周期:
                开始:python文件执行则开始。
                结束:python文件运行完毕后结束。
        3、局部名称空间,可以有多个
            存放的名字:在调用函数时,运行函数体代码过程中产生的函数内的名字。
            示例:func=函数的内存地址,是全局命名空间,a和b数据局部命名空间
                def func():
                    a=111
                    b=222
            存活周期:
                开始:在调用函数时存活。
                结束:在函数调用完毕后则销毁。
    
    
      (2)三种名称空间的加载顺序
    三种名称空间的加载顺序:
        内置名称空间》全局名称空间》局部名称空间
        在运行python解释器时:内置名称空间和全局名称空间一定存在。局部名称空间可以在调用函数时在创建。
    三种名称空间的销毁顺序:
        局部名称空间》全局名称空间》内置名称空间
        (3)三种名称空间的查找名字的优先级
    三种名称空间的查找优先级:从当前所在位置开始,逐层向上一级查找,
    内置名称空间
    全局名称空间
    局部名称空间
    局部名称空间没有去全局名称空空间,全局名称空间没有再去内置名称空间。
    查找局部的
    input = 333  # 全局的
    def func():
        input = 444  # 局部的
        print(input)
    
    func()  # 444
    
    查找全局的
    input = 333  # 全局的
    def func():
        # input = 444  # 局部的
        print(input)
    
    func()  # 333
    
    查找内置的
    # input = 333  # 全局的
    def func():
        # input = 444  # 局部的
        print(input)
    
    func()  # <built-in function input> # 内置的
    从当前所在位置开始,逐层向上一级查找
    # 示范1:名称空间实例:查找顺序
    # x = 111
    # def func():
    #     print(x)  # 111
    #     print(y)  # 222
    # y = 222
    # func()  # 111
    
    # 示范2:名称空间的“嵌套”关系,是以定义阶段为准,与调用位置无关
    x = 1
    def func():  # 此处为局部的
        print(x)  # 嵌套的为全局的x=1
    
    def foo(): # 此处为局部的
        x = 222  # 在此处定义个x =222
        func()
    
    foo()  # 结果为1 重点:名称空间的“嵌套”关系,是以定义阶段为准,与调用位置无关
    # 实例3:函数的嵌套定义,从当前位置向上一层进行查找。
    input = 111  # 当此处被注释打印<built-in function input>
    def f1():
        input = 222  # 当此处被注释打印111
        def f2():
            input = 333  # 当此处被注释打印222
            print(input)
        f2()
    f1()  # 输出结果:333

    如下图所示:
    # 实例4:查找顺序以定义阶段为准
    x = 111
    def func():
        print(x) # 此处的x为局部的,当语法扫描到此处时候,该处的x未定义
        x = 222  # 当此处定义了x=222时此处出现的语法逻辑上错误,针对变量需要先定义后使用
    
    func()  #报错: UnboundLocalError: local variable 'x' referenced before assignment
    # 实例5:
    x = 111
    def func():
        x = 222  # 为避免实例4的错误,应在此处定义x
        print(x)
        # x = 222
    
    func()
    3、作用域:作用范围,对名称空间归类,有两大类(全局和局部)
    (1)全局作用域:内置名称空间、全局名称空间
           1、全局存活:除非被删除否则在文件执行过程中存活
     2、全局有效:被所有函数共享,在任意位置都可以使用。
    # 不同函数内的名字独立
    def foo():
    x = 111
    print(x,id(x))

    def bar():
    x = 222
    print(x,id(x))

    foo() # 111 140715383776352
    bar() # 222 140715383779904
    # 全局存活,全局有效
    x = 111
    def foo():
    print(x,id(x))

    def bar():
    print(x,id(x))
    foo() # 111 140715385939040
    bar() # 111 140715385939040
        (2)局部作用域 :局部名称空间的名字
         1、临时存活:函数在调用时临时生成,函数在调用结束后释放
         2、局部有效:只能在函数内使用它
    def func(x):
        def f1():
            def f2():
                print(x)

      LEGB:

    # 名称空间分为四个:LEGB为便于记忆 L;local,E:enclosing, G:global,B:built-in
    # 局部名称空间分为两类:
    # B
    # G
    def f1():
        # E
        def f2():
            # E:enclosing
            def f3():
                # L:local
                print()
         global
    # 实例1:修改全局变量
    # x = 111
    # def func():
    #     # global x  # 修改全局变量
    #     x = 222
    #     print(x)
    #
    # func()  # 222
    # print(x)  # 111
    
    # 实例2:如果想要在局部修改全局的名字的对应的值(这里针对不可变类型,必须使用global),需要使用global修改全局变量
    # x = 111
    # def func():
    #     global x  # 声明x这个名字时全局的名字,不在早遭新的名字了
    #     x = 222
    #     print(x)
    #
    # func()  # 222
    # print(x)  # 222
    
    # 实例3:针对可变类型
    # l = [111,222]
    # def func():
    #     l = 333
    #     print(l)
    #
    # func()  # 333
    # print(l)  # [111, 222]
    
    l=[1,2,3]
    def func():
    global l # 针对不可变类型,有global和无global的效果是一样的
    l.append(4)

    func()
    print(l) # [1, 2, 3, 4]
    # 体验一下有无调用的效果
    # def func():
    #     global x
    #     x = 111
    # print(x)  # NameError: name 'x' is not defined
    
    def func():
        global x
        x = 111
    func()
    print(x)  # 111
    nonlocal作用
    # nonlocal(了解):实例1:修改函数外层函数包含的名字对应的值(不可变类型)
    # x = 0
    # def f1():
    #     x = 11
    #     def f2():
    #         global x  # 修改全局变量也就是说把x=0的值改成了22
    #         x = 22
    #     f2()
    #     print("全局的x变化后查看f1内的x:",x)   # f1内的x: 11,发现此处的函数没有变化,如果我想改变它,该如何办?使用nonlocal
    # f1()
    # print(x)  # 22
    
    # nonlocal(了解):实例2
    # x = 0
    # def f1():
    #     x = 11
    #     def f2():
    #         nonlocal x  # 从当前层的外一层开始找,没有就报错,SyntaxError: no binding for nonlocal 'x' found
    #         x = 22
    #     f2()
    #     print("全局的x变化后查看f1内的x:",x)   # f1内的x: 22
    # f1()
    # print(x)  # 0
    
    # nonlocal(了解):实例3
    x = 0
    def f1():
        x = []  # 此处如果时可变类型,不用声明了,可以直接修改
        def f2():
            x.append(3333)
        f2()
        print("全局的x变化后查看f1内的x:",x)   # f1内的x: [3333]
    f1()
    print(x)  # 0
    针对名称空间的练习操作:
    # 作业要求:下述所有代码画图以及分析代码执行流程
    # 1、以定义阶段为准,先画出名称空间的嵌套关系图
    # 2、然后找到调用函数的位置,写出函数调用时代码的执行过程,涉及到名字的查找时,参照1中画好
    #    的嵌套图,标明查找顺序,一层一层直到找到位置7
    
    # # ===================题目一===================
    input=333
    def func():
        input=444
        print(input)
    func()
    print(input)

     

    # # ===================题目二===================
    # def func():
    #     print(x)
    # x=111
    #
    # func()
    从局部开始找x,局部没有去全局找,找到了x=111
    # # ===================题目三===================
    # x=1
    # def func():
    #    print(x)
    #
    #
    # def foo():
    #     x=222
    #     func()
    # x = 333
    # foo()  # 333
    

     # # ===================题目四===================

    input=111  # 第四次注释
    def f1():
    def f2():
    # input=444 # 第一次注释
    print(input)
    # input=222 # 第二次注释

    f2()
    # input = 333 # 第三次注释
    f1()
    # 不注释得到的结果:444
    # 第一次注释得到的结果:222
    # 第二次注释得到的结果:333
    # 第三次注释得到的结果:111
    # 第四次注释得到的结果:<built-in function input>

     

    
    

     # # ===================题目五===================

    # x=111
    # def func():
    #     print(x) #
    #     x=222
    #
    # func()
    #
    #
    # # ===================题目六===================
    # x=111
    #
    # def foo():
    #     print(x,)
    #
    # def bar():
    #     print(x)
    #
    # foo()
    # bar()
    #
    # # ===================题目七===================
    # x=1
    # def func2():
    #     func1()
    #
    # x=2
    # def func1():
    #     print(x)
    #
    # x=3
    #
    # func2()
    #
    # # ===================题目八===================
    # 1、如下全局变量记录了当前登录用户,编写登录功能,一旦用户登录成功,则将全局变量赋值为当前登录的用户名
    # login_user=None
    # 2、针对之前编写的查询余额的功能,添加额外的逻辑:如果用户没有登录,则先执行登录功能
    
    
    # 验证使用locals()和globals()函数的作用,查看名称空间
    x = 1
    def foo():
        x = 2
        print("局部名称空间:",x)
        # 查看局部名臣空间,结果以字典形式展现
        print(locals())  # {'x': 2}
    foo()
    print("全局名称空间:",x)
    # 查看全局名称空间,结果以字典形式展示
    print(globals())
    # {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000020CA8200970>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/pycharm/oldboy_29/day015/test015/test015_10global和local.py', '__cached__': None, 'x': 1, 'foo': <function foo at 0x0000020CA83495E0>}
     
  • 相关阅读:
    [CF590C] Three States
    [CF767B] The Queue
    [CF1296F] Berland Beauty
    [CF3D] Least Cost Bracket Sequence
    YUV420 转 RGB 测试
    [POI2012] TOU-Tour de Byteotia
    [CF576C] Points on Plane
    [CF191C] Fools and Roads
    [CF1485C] Floor and Mod
    [CF1399D] Binary String To Subsequences
  • 原文地址:https://www.cnblogs.com/liunaixu/p/12593217.html
Copyright © 2020-2023  润新知