彩虹然

rainbow-ran

Python3.7之namespace

一、namespace

在 Python 中,名字是一个字符串对象,它与它指向的对象构成一个{name:object}关联。
也可以把一个namespace理解为一个字典。

二、作用域

Python 中name-object的关联存储在不同的作用域中,各个不同的作用域是相互独立的。
而我们就在不同的作用域中搜索name-object。
Python中使用变量名引用对象,需要使用该变量时,就在命名空间中进行搜索,获取对应的对象。
名称空间有四种:LEGB

  • locals 是函数内的名字空间,包括局部变量和形参
  • enclosing 在嵌套函数中外部函数的名字空间, 若fun2嵌套在fun1里,对fun2来说,fun1的名字空间就是enclosing(闭包中常见)
  • globals 当前的模块空间,模块就是一些py文件。也就是说,globals()类似全局变量
  • builtins 内置模块的名字空间,也就是内置变量或者内置函数的名字空间,print(dir(builtins))可查看包含的值

当程序引用某个变量的名字时,就会从当前名字空间开始查找,查找顺序(LEGB):
locals -> enclosing function -> globals -> builtins

三、生命周期

1.builtins 在python解释器启动的时候,便已经创建,直到退出。
2.globals 在模块定义被读入时创建,通常也一直保存到解释器退出。
3.locals 在函数调用时创建,直到函数返回,或者抛出异常之后,销毁。
4.递归函数每一次均有自己的名字空间。

四、代码引例

print('1. globals: ', globals())  # 全局名称空间,此时不包含a
a = 1000000000  # 定义全局变量a


def func():
    print('1. func locals: ', locals())  # 此时函数内的名称空间为空
    a = 1  # 局部变量a
    b = 2
    global p  # 函数内部调用global声明的时候,可将变量存储在globals中
    p = 9999

    def inner_func():
        print('1. inner_func locals: ', locals())
        # 此处locals中已经有了nonlocal声明的a,且此时的a为外部嵌套函数里的值
        m = 3
        n = 4
        nonlocal a  # nonlocal关键字来修改外部嵌套函数的名字空间。只能在内部嵌套函数使用。
        a = m + n
        print(a)
        print('2. inner_func locals: ', locals())

    inner_func()
    print(a, b, p)
    print('2. func locals: ', locals())


func()
print(a)
print('2. globals: ', globals())

'''
1. globals:  {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000178D6FD64A8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/Desktop/新建文件夹/practice2.py', '__cached__': None}
1. func locals:  {}
1. inner_func locals:  {'a': 1}
7
2. inner_func locals:  {'a': 7, 'm': 3, 'n': 4}
7 2 9999
2. func locals:  {'b': 2, 'inner_func': <function func.<locals>.inner_func at 0x00000178D8C2A6A8>, 'a': 7}
1000000000
2. globals:  {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000178D6FD64A8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/Desktop/新建文件夹/practice2.py', '__cached__': None, 'a': 1000000000, 'func': <function func at 0x00000178D6F8C268>, 'p': 9999}
'''
posted @ 2020-01-16 16:16  彩虹然  阅读(683)  评论(0编辑  收藏  举报