如何防止模块被重复导入?
在写Python模块的时候,有没有办法防止它被客户端代码重复导入呢?就像C/C++的头文件那样:
#ifndef XXX
#define XXX
...
#endif
非常感谢!
3 个回答
23
导入的模块会被缓存,也就是说它们只会运行一次。之后再导入同样的模块,只需要花一点时间去查找一下已经导入的模块就可以了。
28
正如其他回答所提到的,Python 通常在遇到第二次导入同一个模块时,不会重新加载这个模块。相反,它会从 sys.modules
中返回一个缓存的版本,而不会执行模块中的任何代码。
不过,有几个需要注意的陷阱:
把主模块当作普通模块导入,实际上会在不同的名称下创建两个相同模块的实例。
这是因为在程序启动时,主模块会被设置为名称
__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
中不同的条目来导入稍微不同的导入语句,结果却指向同一个模块。 - 在之前的导入失败了一半后,再次尝试导入同一个模块。
- 使用
55
在Python中,模块不会被多次导入。也就是说,如果你运行两次导入同一个模块,它不会重新加载这个模块。如果你想让它重新加载,就需要使用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