导入函数中的__globals__与主模块中函数的__globals__有很大不同

时间:2013-05-29 17:47:35

标签: python

档案 a.py

def f():
  pass

文件 main.py

import a
print("f globals")
print(a.f.__globals__)

def g():
  pass

print("g globals")
print(g.__globals__)

a.f.__globals__g.__globals__拥有更多元素。初看起来,内置函数和类型似乎在a.f.__globals__中。为什么这两个词典不同?

1 个答案:

答案 0 :(得分:4)

您正在查看模块名称空间。 f()全局变量与g()全局变量不同,因为它们都存在于不同的模块中。

如果使用vars()(对于main中的全局变量)和vars(a)(对于模块a的全局变量),您将看到相同的全局命名空间:

print(sorted(vars(a).keys() - vars()))
# prints ['__initializing__', 'f'], only `a` has `f` defined, the `__initializing__` value is a flag used by the import machinery
print(sorted(vars().keys() - vars(a)))
# prints ['a', 'g'], only `main` has imported `a` and defined function `g`

每个模块都有自己的命名空间,globals()不是全局解释器,它们只是模块全局。导入模块意味着您要导入对该命名空间的引用,或者在该命名空间中创建名称​​的引用。

来自datamodel documentation模块对象:

  

模块对象具有由字典对象实现的命名空间(这是模块中定义的函数的__globals__属性引用的字典)

和关于函数对象:

  

__globals__:对包含函数全局变量的字典的引用 - 定义函数的模块的全局命名空间。

主脚本的__builtins__键仅指向已扩展为字典的导入模块中的__builtins__模块。这些都是一样的,真​​的。