2013-09-29 20 views
21

我懷疑我想清除。當我在Python中導入模塊兩次時發生了什麼

考慮以下模塊命名爲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一次。它不應該打印兩次?

+0

的行爲是正確的 –

回答

28

沒有,如果一個模塊已被導入,它不會再次加載。

您只需獲取已導入模塊的引用(它將來自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,你只會得到一個新的參考吧。而已。


注意,這意味着模塊應設計成不會有副作用(例如打印的東西)時,他們進口

在交互式會話之外重新加載模塊通常不是很好的做法(儘管它有它的用例) - 其他答案將詳細說明如何做到這一點。

1

模塊只在第一次執行import語句時加載。另見reload()this question。您可以檢查sys.modules以查明哪些模塊已被加載。

3

任何python腳本只會重新加載一次模塊。要重新加載它,使用:

reload()  # Python 2 

imp.reload() # Python 3 
相關問題