【发布时间】:2010-01-08 17:49:45
【问题描述】:
在编写python模块时,有没有办法防止它被客户端代码导入两次?就像 c/c++ 头文件一样:
#ifndef XXX
#define XXX
...
#endif
非常感谢!
【问题讨论】:
在编写python模块时,有没有办法防止它被客户端代码导入两次?就像 c/c++ 头文件一样:
#ifndef XXX
#define XXX
...
#endif
非常感谢!
【问题讨论】:
Python 模块不会多次导入。只运行两次 import 不会重新加载模块。如果你想重新加载它,你必须使用reload 语句。这是一个演示
foo.py 是一个单行模块
print("I am being imported")
这是多次导入尝试的屏幕记录。
>>> 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
【讨论】:
reload() 不会修复对旧模块的任何引用,因此实际上并没有那么有用。
导入被缓存,并且只运行一次。额外的导入只花费sys.modules 中的查找时间。
【讨论】:
如其他答案中所述,Python 通常在遇到第二个导入语句时不会重新加载模块。相反,它从sys.modules 返回其缓存版本,而不执行任何代码。
但是有几个陷阱值得注意:
将主模块作为普通模块导入有效地创建了同一模块的两个不同名称的实例。
这是因为在程序启动期间the main module is set up with the name __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
因此,按照here 的建议,最好将主模块保持在最低限度,并将其大部分功能导出到外部模块。
This answer 指定了另外两种可能的情况:
sys.path 中不同条目的导入语句略有不同,导致相同的模块。【讨论】: