python - 当一个模块被导入两次时会发生什么?

标签 python module

我有一个疑问,希望得到澄清。

考虑以下名为 ex_1.py 的模块:

print("Hello, I'm ex_1")
def greet(name):
 print("Hello, "+name+" nice to meet you! ")

现在考虑另一个名为 1_client_ex_1.py 的文件,它将导入 ex_1.py 模块。

import ex_1.py

现在,当我执行此文件时,我得到的输出为:

Hello, I'm ex_1

正如预期的那样。

但是当我更改为 1_client_ex_1.py 时:

import ex_1.py
import ex_1.py

并执行它,它仍然只打印一次 Hello, I'm ex_1 。难道不应该打印两次吗?

最佳答案

没什么,如果模块已经导入,则不会再次加载。

您将只需获得对已导入模块的引用(它将来自 sys.modules )。

要获取已导入的模块列表,您可以查找 sys.modules.keys() (请注意,urllib 这里导入了很多其他模块):

>>> import sys
>>> print len(sys.modules.keys())
44
>>> print sys.modules.keys()
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'abc', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', 'virtualenvwrapper', '_osx_support', 'codecs', 'readline', 'os.path', 'sitecustomize', 'signal', 'traceback', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']
>>> import urllib
>>> print len(sys.modules.keys())
70
>>> print sys.modules.keys()
['cStringIO', 'heapq', 'base64', 'copy_reg', 'sre_compile', '_collections', '_sre', 'functools', 'encodings', 'site', '__builtin__', 'sysconfig', 'thread', '_ssl', '__main__', 'operator', 'encodings.encodings', '_heapq', 'abc', 'posixpath', '_weakrefset', 'errno', '_socket', 'binascii', 'encodings.codecs', 'urllib', 'sre_constants', 're', '_abcoll', 'collections', 'types', '_codecs', 'encodings.__builtin__', '_struct', '_warnings', '_scproxy', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'string', 'warnings', 'UserDict', 'struct', 'encodings.utf_8', 'textwrap', 'sys', 'ssl', 'virtualenvwrapper', '_osx_support', 'codecs', 'readline', 'os.path', 'strop', '_functools', 'sitecustomize', 'socket', 'keyword', 'signal', 'traceback', 'urlparse', 'linecache', 'itertools', 'posix', 'encodings.aliases', 'time', 'exceptions', 'sre_parse', 'os', '_weakref']
>>> import urllib #again!
>>> print len(sys.modules.keys()) #has not loaded any additional modules
70

让我们尝试一下:

import sys
>>> sys.modules["foo"] = "bar"  # Let's pretend we imported a module named "foo", which is a string.
>>> print __import__("foo")
bar  # Not a module, that's my string!

如您所见,如果在 sys.modules 中找到模块,您将获得对它的新引用。就是这样。

<小时/>

请注意,这意味着模块的设计应确保在导入时不会产生副作用(例如打印内容)

在交互式 session 之外重新加载模块通常也不是一个很好的做法(尽管它有其用例) - 其他答案将详细说明如何执行此操作。

关于python - 当一个模块被导入两次时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54803064/

相关文章:

python - 使用 Pillow 创建隐写隐藏图像

module - 将不合格的模板实例化范围中的项目带入本地范围

Purescript 中的字符串连接

ruby - 模块中的动态方法?

Python 在线切换

python - AWS Cognito 作为网站的 Django 身份验证后端

python - 我需要对我的 python 代码做些什么才能让它成为一个模块?

apache-flex - 错误 : Could not resolve to a component implementation

python - 如何将 python 日志输出存储到 mongoDb 中

python - 为什么删除 else 会减慢我的代码速度?