我今天必须阅读并修复一些非常糟糕的脚本,我感到困惑,因为我不明白他们为什么会工作。要清楚,我绝不会做这样的事情。我的问题是指命名空间如何在这种情况下工作,而不是为什么这是一个坏主意或如何做得更好。
无论如何,最简单形式的情况可以用两个文件重现。
test.py
:
import math
math.myvar = "Is this a local variable?"
math.pi = 1.2345
import u
u.py
:
import math
print(math.myvar)
print(math.pi)
现在,令我惊讶的是,python test.py
运行会打印myvar
,错误的值为pi。当然,如果import math
中没有u.py
,则不会打印myvar
。这是怎么发生的?我虽然导入的模块完全是本地的。
答案 0 :(得分:4)
模块是全球单身人士。它们存储在sys.modules
映射中,以防止每次在某个地方使用时都必须加载每个模块。
模块中的所有全局变量都作为模块对象的属性公开; math.pi
就是这样一个全球性的。您可以通过赋值来更改这些全局变量,并且因为模块是单例对象,所以对模块对象的每个引用都将看到更改。
请记住,Python名称是引用;名称math
确实是模块的“本地”,但它仍然是对全局<module 'math' from '/usr/lib/python2.7/lib-dynload/math.so'>
对象的引用。