python 如何防止一个模块被导入两次?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2029523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to prevent a module from being imported twice?
提问by KL.
When writing python modules, is there a way to prevent it being imported twice by the client codes? Just like the c/c++ header files do:
编写python模块时,有没有办法防止它被客户端代码导入两次?就像 c/c++ 头文件一样:
#ifndef XXX
#define XXX
...
#endif
Thanks very much!
非常感谢!
回答by Noufal Ibrahim
Python modules aren't imported multiple times. Just running import two times will not reload the module. If you want it to be reloaded, you have to use the reload
statement. Here's a demo
Python 模块不会多次导入。只运行两次 import 不会重新加载模块。如果要重新加载它,则必须使用该reload
语句。这是一个演示
foo.py
is a module with the single line
foo.py
是单行的模块
print("I am being imported")
And here is a screen transcript of multiple import attempts.
这是多次导入尝试的屏幕记录。
>>> import foo
Hello, I am being imported
>>> import foo # Will not print the statement
>>> reload(foo) # Will print it again
Hello, I am being imported
回答by Ignacio Vazquez-Abrams
Imports are cached, and only run once. Additional imports only cost the lookup time in sys.modules
.
导入被缓存,并且只运行一次。额外的导入只会花费sys.modules
.
回答by Yoel
As specified in other answers, Pythongenerally doesn't reload a module when encountering a second import statement for it. Instead, it returns its cached version from sys.modules
without executing any of its code.
如其他答案中所述,Python在遇到第二个导入语句时通常不会重新加载模块。相反,它在sys.modules
不执行任何代码的情况下返回其缓存版本。
However there are several pitfalls worth noting:
然而,有几个陷阱值得注意:
Importing the main module as an ordinary module effectively creates two instances of the same module under different names.
This occurs because during program startup the main module is set up with the name
__main__
. Thus, when importing it as an ordinary module, Pythondoesn't detect it insys.modules
and imports it again, but with its proper name the second time around.Consider the file /tmp/a.pywith the following content:
# /tmp/a.py import sys print "%s executing as %s, recognized as %s in sys.modules" % (__file__, __name__, sys.modules[__name__]) import b
Another file /tmp/b.pyhas a single import statement for a.py(
import a
).
Executing /tmp/a.pyresults in the following output:root@machine:/tmp$ python a.py a.py executing as __main__, recognized as <module '__main__' from 'a.py'> in sys.modules /tmp/a.pyc executing as a, recognized as <module 'a' from '/tmp/a.pyc'> in sys.modules
Therefore, it is best to keep the main module fairly minimal and export most of its functionality to an external module, as advised here.
This answerspecifies two more possible scenarios:
- Slightly different import statements utilizing different entries in
sys.path
leading to the same module. - Attempting another import of a module after a previous one failed halfway through.
- Slightly different import statements utilizing different entries in
将主模块作为普通模块导入可以有效地以不同的名称创建同一模块的两个实例。
发生这种情况是因为在程序启动期间主模块设置了名称
__main__
。因此,当将它作为普通模块导入时,Python不会检测到它sys.modules
并再次导入它,而是第二次使用它的正确名称。考虑具有以下内容的文件/tmp/a.py:
# /tmp/a.py import sys print "%s executing as %s, recognized as %s in sys.modules" % (__file__, __name__, sys.modules[__name__]) import b
另一个文件/tmp/b.py有一个用于a.py(
import a
) 的导入语句。
执行/tmp/a.py 会产生以下输出:root@machine:/tmp$ python a.py a.py executing as __main__, recognized as <module '__main__' from 'a.py'> in sys.modules /tmp/a.pyc executing as a, recognized as <module 'a' from '/tmp/a.pyc'> in sys.modules
因此,最好是保持主模块相当小,且大部分的功能导出到外部模块,如建议在这里。
此答案指定了另外两种可能的情况:
- 稍微不同的导入语句使用不同的条目来
sys.path
引导同一个模块。 - 在前一个模块中途失败后尝试再次导入模块。
- 稍微不同的导入语句使用不同的条目来