python 之 globals 和 locals

󰃭 2017-06-06

globalslocals 两个内置函数, 分别用于表示全局变量和局部变量集合

globals

获取全局变量

这里的全局变量 是模块内的全局变量, 如下

g_name = 'Yi_Zhi_Yu'
print(globals())

输出如下

{'__name__': '__main__', '__doc__': '\n测试globals函数\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10c44c208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/xxxx/globals.py', '__cached__': None, 'g_name': 'Yi_Zhi_Yu'}

globals 输出了模块内的全局变量, 除了我们添加的g_name, 还有一些默认的属性列表

定义全局变量

如果我们通过globals 定义的全局变量, 是可以直接使用的, 如下

g = globals()
g['g_setted_name'] = 'Tony'
print(g_setted_name) # Tony

globals 里的 g_setted_name 可以直接作为变量使用

在模块内定义的全局变量或者内置的全局变量, 会以key,value 的形式存储在globals 的字典中

有时, 我们从一个模块中的全局作用域, 用from xxx import var1 的方式引入的var1 其实就是以全局变量的形式存储在了globals 中, 所以我们可以直接使用var1, 如下

global_a.py

global_a_name = 'global_a_name_value'

globals.py

from globals_a import global_a_name
print(global_a_name) # global_a_name_value
print(globals()) # 包含`global_a_name` 这个key, value 是 `global_a_name_value`

locals

locals 表示局部变量的集合, 如果是模块级别的, localsglobals 的输出是一样的

还是上面的globals.py文件

from globals_a import global_a_name
print(global_a_name) # global_a_name_value
print(globals()) 
print(locals())

输出如下:

{'__name__': '__main__', '__doc__': '\n测试globals函数\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b8e8208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/xxxx/globals.py', '__cached__': None, 'global_a_name': 'global_a_name_value'}

{'__name__': '__main__', '__doc__': '\n测试globals函数\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b8e8208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/xxxx/globals.py', '__cached__': None, 'global_a_name': 'global_a_name_value'}

但在某个函数内的话, locals 表示的就是该函数内的局部变量集合

def test(a):
    b = 'b_v'
    print(locals())
	print(globals)
test('a_v')

locals 输出的是包含a,b 两个变量的字典

{'b': 'b_v', 'a': 'a_v'}

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10d8b5208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/xxxx/locals.py', '__cached__': None, 'test': <function test at 0x10d7d6ea0>}

如果在函数内引入模块会怎么样呢

def test(a):
    b = 'b_v'
    from globals_a import global_a_name
    print(locals())
    print(globals())

test('a_v')

locals 的输出是 {'global_a_name': 'global_a_name_value', 'b': 'b_v', 'a': 'a_v'}, 在函数内的引入被写入到的是局部变量集合

globals输出里并不包含这个global_a_name

变量查询顺序

实际的变量查询是有一个顺序的

  1. 局部命名空间(locals)
  2. 全局命名空间(globals)
  3. 内置命名空间, 内置变量