当一个模块被导入两次时会发生什么? [英] What happens when a module is imported twice?

查看:26
本文介绍了当一个模块被导入两次时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个疑问,我想被清除.

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

print("你好,我是 ex_1")定义问候(姓名):print("你好,"+姓名+"很高兴认识你!")

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

导入 ex_1.py

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

你好,我是 ex_1

正如预期的那样.

但是当我将 1_client_ex_1.py 改为:

导入 ex_1.py导入 ex_1.py

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

解决方案

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

您将简单地获得对已导入模块的引用(它将来自 sys.modules).

要获取已经导入的模块列表,可以查找sys.modules.keys()(注意urllib这里导入了一个lot 其他模块):

<预><代码>>>>导入系统>>>打印 len(sys.modules.keys())44>>>打印 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']>>>导入 urllib>>>打印 len(sys.modules.keys())70>>>打印 sys.modules.keys()['cStringIO', 'heapq', 'base64', 'copy_reg', 'sre_compile', '_collections', '_sre', 'functools', 'encodings', 'site', '__builtin__', 'sysconfig', '线程', '_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']>>>导入 urllib #again!>>>打印 len(sys.modules.keys()) #还没有加载任何额外的模块70

让我们试一试:

导入系统>>>sys.modules["foo"] = "bar" # 假设我们导入了一个名为foo"的模块,它是一个字符串.>>>打印 __import__("foo")bar # 不是模块,那是我的字符串!

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

<小时>

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

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

I have a doubt that I would like to get cleared up.

Consider the following module named ex_1.py:

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

Now consider another file called 1_client_ex_1.py that will import ex_1.py module.

import ex_1.py

Now when I execute this file, I get the output as :

Hello, I'm ex_1

As expected.

But when I change to 1_client_ex_1.py to:

import ex_1.py
import ex_1.py

and execute it, it still prints only Hello, I'm ex_1 once. Shouldn't it print it twice?

解决方案

Nothing, if a module has already been imported, it's not loaded again.

You will simply get a reference to the module that has already been imported (it will come from sys.modules).

To get a list of the modules that have already been imported, you can look up sys.modules.keys() (note that urllibhere imports a lot of other modules):

>>> 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

Let's give it a whirl:

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!

As you can see, if a module is found un sys.modules, you'll just get a new reference to it. That's it.


Note that this means that modules should be designed so as to not have side effects (such as printing stuff) when they're imported.

Reloading modules, outside of an interactive session, is usually not a very good practice either (although it has its use cases) - the other answers will detail how you'd do this.

这篇关于当一个模块被导入两次时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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