作为序言,我想我可能已经弄清楚了如何让这段代码工作(基于 Changing module variables after import ),但我的问题实际上是关于为什么会发生以下行为,以便我了解以后不应该做什么。
我有三个文件。第一个是 mod1.py:
# mod1.py
import mod2
var1A = None
def func1A():
global var1
var1 = 'A'
mod2.func2()
def func1B():
global var1
print var1
if __name__ == '__main__':
func1A()
接下来我有 mod2.py:
# mod2.py
import mod1
def func2():
mod1.func1B()
终于有了 driver.py:
# driver.py
import mod1
if __name__ == '__main__':
mod1.func1A()
如果我执行命令 python mod1.py
,则输出为 None
。根据我上面引用的链接,似乎 mod1.py
被导入为 __main__
和 mod1.py
被导入之间存在一些区别来自 mod2.py
。因此,我创建了 driver.py
。如果我执行命令 python driver.py
然后我得到预期的输出:A
。我有点看出区别,但我并没有真正看到其中的机制或原因。这是怎么发生的,为什么会发生?同一个模块存在两次似乎违反直觉。如果我执行 python mod1.py
,是否可以访问 __main__
版本的 mod1.py
中的变量而不是mod2.py
导入的版本?
最佳答案
__name__
变量总是包含模块的名称,除非 当文件作为脚本加载到解释器中时。 然后该变量被设置为字符串'__main__'
。
毕竟,脚本随后作为整个程序的主文件运行,其他一切都是该主文件直接或间接导入的模块。通过测试 __name__
变量,您可以检测文件是否已作为模块导入或直接运行。
在内部,模块被赋予一个命名空间字典,它作为每个模块的元数据的一部分存储在 sys.modules
中。主文件,即执行的脚本,存储在与 '__main__'
相同的结构中。
但是当您将文件作为模块导入时,python 首先查看 sys.modules
以查看该模块之前是否已经导入。因此,import mod1
意味着我们首先在 sys.modules
中查找 mod1
模块。如果 mod1
还不存在,它将创建一个带有命名空间的新模块结构。
因此,如果您同时运行 mod1.py
作为主文件,然后将其作为 python 模块导入,它将得到 两个sys.modules
中的 em> 命名空间条目。一个是 '__main__'
,然后是 'mod1'
。这两个命名空间是完全独立的。您的全局 var1
存储在 sys.modules['__main__']
中,但 func1B
正在查找 sys.modules['mod1 ']
对于 var1
,它是 None
。
但是当你使用python driver.py
时,driver.py
成为程序的'__main__'
主文件,而mod1
将只导入一次到 sys.modules['mod1']
结构中。这一次,func1A
将 var1
存储在 sys.modules['mod1']
结构中,这就是 func1B
会找到。
关于python - 导入模块 : __main__ vs import as module,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13181559/