2013-09-29 16 views
21

Mam wątpliwości, czy chciałbym uzyskać wyjaśnienie.co się dzieje, gdy dwukrotnie importuję moduł w pythonie

Rozważmy następujący moduł nazwany ex_1.py:

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

Rozważmy teraz inny plik o nazwie 1_client_ex_1.py że będą importować moduł ex_1.py.

import ex_1.py 

Teraz kiedy wykonać ten plik, mam wyjścia jak:

Hello, I'm ex_1 

jak oczekiwano.

Ale kiedy zmieni się 1_client_ex_1.py do:

import ex_1.py 
import ex_1.py 

i wykonać go, to nadal drukuje tylko Hello, I'm ex_1 raz. Nie powinien wydrukować go dwa razy?

+0

zachowanie jest poprawne –

Odpowiedz

28

Nic, jeśli moduł został już zaimportowany, nie jest ponownie ładowany.

Po prostu otrzymasz odwołanie do modułu, który został już zaimportowany (będzie pochodził z sys.modules).

Aby uzyskać listę modułów, które już zostały przywiezione, można patrzeć sys.modules.keys() (zauważ, że urllib tutaj importuje dużo innych modułów):

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

Dajmy jej wir:

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! 

Jak widać, jeśli moduł znajduje un sys.modules, będziesz po prostu nowy odnośnik do niego. to jest to!


Zauważ, że oznacza to, że moduły powinny być zaprojektowane tak, aby nie mają skutków ubocznych (takich jak drukowanie rzeczy), gdy są one importowane.

Ponowne ładowanie modułów, poza sesją interaktywną, zazwyczaj nie jest dobrą praktyką (chociaż ma również swoje zastosowania) - pozostałe odpowiedzi szczegółowo opisują, w jaki sposób można to zrobić.

1

Moduł jest ładowany tylko przy pierwszym wykonaniu instrukcji import. Zobacz także reload() i this question. Możesz sprawdzić, sys.modules, aby dowiedzieć się, które moduły zostały już załadowane.

3

Każdy skrypt Pythona przeładuje moduł tylko raz. Aby przeładować go używać:

reload()  # Python 2 

i

imp.reload() # Python 3 
Powiązane problemy