Python locals()与globals()与命名空间

Python内置2个函数,locals()globals(),分别返回当前位置的局部变量和全局变量的字典形式。

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000002050880>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'D:/www/21yi.com/hello.py', '__cached__': None}

如何更深入理解这两个函数呢?首先要理解Python的命名空间

一. 什么是命名空间

首先,命名空间是个字典,用来记录变量的轨迹。

  • 每个函数都有自已的命名空间 —— 局部名字空间:记录函数的变量,包括函数的参数 和局部定义的变量
  • 每个模块的命名空间 —— 全局名字空间,记录模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量
  • 内置命名空间,任何模块均可访问它,它存放着内置的函数和异常

二. 变量查找的顺序

当一个函数要使用变量 x 时候,Python会到所有的命名空间按一定顺序去寻找变量。顺序分别是:

  1. 局部命名空间 - 特指当前函数或类的方法。如果函数定义了一个局部变量 x,Python将使用
      这个变量,然后停止搜索。
  2. 全局命名空间 - 特指当前的模块。如果模块定义了一个名为 x 的变量,函数或类,Python
      将使用这个变量然后停止搜索。
  3. 内置命名空间 - 对每个模块都是全局的。作为最后的尝试,Python将假设 x 是内置函数或变量。

如果找不到 变量 x,将抛出NameError异常

Traceback (most recent call last):
File "D:/www/21yi.com/hello.py", line 14, in
print(x)
NameError: name 'x' is not defined

三. local() 局部变量和globals()的作用示例

def hello(x, y):
x = 1
y = 99
for i in range(5):
x += i
y += i
z = x + y
print(locals())

hello(1, 2)
print(globals())

1. 观察局部变量的变化:

{'x': 1, 'y': 99, 'i': 0, 'z': 100}
{'x': 2, 'y': 100, 'i': 1, 'z': 102}
{'x': 4, 'y': 102, 'i': 2, 'z': 106}
{'x': 7, 'y': 105, 'i': 3, 'z': 112}
{'x': 11, 'y': 109, 'i': 4, 'z': 120}

2. 观察全局变量的变化

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001D00880>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'D:/www/21yi.com/hello.py', '__cached__': None, 'hello': }

 

四. from module import 和 import module的区别

  • import module,模块自身被导入, 但是它保持着自已的命名空间。所以访问需要模块名.函数()或者属性
  • from module import,从另一个模块中导入需要的函数和属性到当前命名空间,可以直接使用
import math
from sys import winver

print(math.pi)
print(winver)
print(locals())

# 结果
#3.141592653589793
#3.8
#{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000000005E0880>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'D:/www/21yi.com/hello.py', '__cached__': None, 'math': , 'winver': '3.8'}

五. Reference

globals() 返回一个字典,字典包含了当前位置的全局变量

locals() 返回一个字典,字典包含了当前位置的局部变量