导入模块:__main__ 与作为模块导入 [英] Importing modules: __main__ vs import as module

查看:32
本文介绍了导入模块:__main__ 与作为模块导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为序言,我想我可能已经想出了如何让这段代码工作(基于 导入后更改模块变量),但我的问题实际上是关于为什么会发生以下行为,以便我了解将来不应该做什么.

To preface, I think I may have figured out how to get this code working (based on Changing module variables after import), but my question is really about why the following behavior occurs so I can understand what to not do in the future.

我有三个文件.第一个是 mod1.py:

I have three files. The first is 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:

Next I have mod2.py:

# mod2.py

import mod1

def func2():
    mod1.func1B()

我终于有了 driver.py:

Finally I have 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 导入的版本?

If I execute the command python mod1.py then the output is None. Based on the link I referenced above, it seems that there is some distinction between mod1.py being imported as __main__ and mod1.py being imported from mod2.py. Therefore, I created driver.py. If I execute the command python driver.py then I get the expected output: A. I sort of see the difference, but I don't really see the mechanism or the reason for it. How and why does this happen? It seems counterintuitive that the same module would exist twice. If I execute python mod1.py, would it be possible to access the variables in the __main__ version of mod1.py instead of the variables in the version imported by mod2.py?

推荐答案

__name__ 变量始终包含模块的名称,除非文件已加载到将解释器改为脚本.然后将该变量设置为字符串'__main__'.

The __name__ variable always contains the name of the module, except when the file has been loaded into the interpreter as a script instead. Then that variable is set to the string '__main__' instead.

毕竟,脚本然后作为整个程序的主文件运行,其他一切都是由该主文件直接或间接导入的模块.通过测试 __name__ 变量,您可以检测文件是否已作为模块导入或直接运行.

After all, the script is then run as the main file of the whole program, everything else are modules imported directly or indirectly by that main file. By testing the __name__ variable, you can thus detect if a file has been imported as a module, or was run directly.

在内部,模块被赋予一个命名空间字典,它作为每个模块元数据的一部分存储在 sys.modules 中.主文件,即执行的脚本,存储在与 '__main__' 相同的结构中.

Internally, modules are given a namespace dictionary, which is stored as part of the metadata for each module, in sys.modules. The main file, the executed script, is stored in that same structure as '__main__'.

但是当您将文件作为模块导入时,python 首先查看 sys.modules 以查看该模块之前是否已导入.所以,import mod1 意味着我们首先在 sys.modules 中查找 mod1 模块.如果 mod1 还不存在,它将创建一个带有命名空间的新模块结构.

But when you import a file as a module, python first looks in sys.modules to see if that module has already been imported before. So, import mod1 means that we first look in sys.modules for the mod1 module. It'll create a new module structure with a namespace if mod1 isn't there yet.

因此,如果您都将 mod1.py 作为主文件运行,并且稍后将其作为 python 模块导入,它将得到 twosys.modules 中的 em> 命名空间条目.一个是 '__main__',然后是 'mod1'.这两个命名空间是完全独立的.您的全局 var1 存储在 sys.modules['__main__'] 中,但 func1B 正在 sys.modules['mod1'] 对于 var1,它是 None.

So, if you both run mod1.py as the main file, and later import it as a python module, it'll get two namespace entries in sys.modules. One as '__main__', then later as 'mod1'. These two namespaces are completely separate. Your global var1 is stored in sys.modules['__main__'], but func1B is looking in sys.modules['mod1'] for var1, where it is None.

但是当你使用python driver.py时,driver.py成为程序的'__main__'主文件,>mod1 将只导入一次 sys.modules['mod1'] 结构.这一次,func1Avar1 存储在 sys.modules['mod1'] 结构中,这就是 func1B> 会找到.

But when you use python driver.py, driver.py becomes the '__main__' main file of the program, and mod1 will be imported just once into the sys.modules['mod1'] structure. This time round, func1A stores var1 in the sys.modules['mod1'] structure, and that's what func1B will find.

这篇关于导入模块:__main__ 与作为模块导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆