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

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

问题描述

首先,我想我可能已经想出了如何使此代码正常工作(基于导入后更改模块变量),但我的问题确实是关于为什么会发生以下行为,以便我以后理解该怎么做.

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.pymod2.py导入之间存在一些区别.因此,我创建了driver.py.如果执行命令python driver.py,则会得到预期的输出:A.我看到了一些区别,但是我并没有真正看到它的机制或原因.这是怎么发生的以及为什么发生的?似乎同一模块将存在两次是违反直觉的.如果执行python mod1.py,是否可以访问mod1.py__main__版本中的变量,而不是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__变量始终包含模块的名称, except 反而. 然后将该变量设置为字符串'__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模块,它将在两个命名空间条目>.一个是'__main__',然后是'mod1'.这两个名称空间是完全分开的.您的全局var1存储在sys.modules['__main__']中,但是func1Bsys.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__ vs作为模块导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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