Pisząc moduły Pythona, czy istnieje sposób, aby zapobiec dwukrotnemu importowaniu przez kody klienta? Podobnie jak pliki nagłówkowe c/C++:Jak zapobiec podwójnemu importowaniu modułu?
#ifndef XXX
#define XXX
...
#endif
Dziękuję bardzo!
Pisząc moduły Pythona, czy istnieje sposób, aby zapobiec dwukrotnemu importowaniu przez kody klienta? Podobnie jak pliki nagłówkowe c/C++:Jak zapobiec podwójnemu importowaniu modułu?
#ifndef XXX
#define XXX
...
#endif
Dziękuję bardzo!
Moduły Pythona nie są importowane wiele razy. Uruchomienie importu dwa razy nie przeładuje modułu. Jeśli chcesz go ponownie załadować, musisz użyć instrukcji reload
. Oto demo
foo.py
jest moduł z jednej linii
print "I am being imported"
A oto zapis ekran wielokrotnych prób importu.
>>> 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
Przywóz jest buforowany i uruchamiany tylko raz. Dodatkowy import kosztuje tylko czas wyszukiwania w sys.modules
.
Jak określono w innych odpowiedzi, Python generalnie nie przeładować moduł gdy napotyka drugą instrukcję import do niego. Zamiast tego zwraca swoją wersję z pamięci podręcznej z sys.modules
bez wykonywania żadnego z jej kodu.
Jednak istnieje kilka pułapek warto zauważyć:
Importowanie głównego modułu jako zwykły moduł skutecznie tworzy dwie instancje tego samego modułu pod różnymi nazwami.
Dzieje się tak, ponieważ podczas uruchamiania programu the main module is set up with the name __main__
. Zatem podczas importowania go jako zwykłego modułu,nie wykrywa go w sys.modules
i ponownie go importuje, ale z właściwą nazwą drugi raz.
Rozważmy plik /tmp/a.py o następującej treści:
# /tmp/a.py
import sys
print "%s executing as %s, recognized as %s in sys.modules" % (__file__, __name__, sys.modules[__name__])
import b
Kolejny plik /tmp/b.py posiada jeden rachunek za import a.py (import a
).
Wykonywanie /tmp/a.py wyniki w następujący wynik:
[email protected]:/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
Dlatego najlepiej jest zachować główny moduł dość minimalne i eksport większość swojej funkcjonalności modułu zewnętrznego, jak poradził here .
This answer określa jeszcze dwa możliwe scenariusze:
sys.path
prowadzące do tego samego modułu.
Należy pamiętać, że 'reload()' nie rozwiąże się żadnych odniesień do starego modułu, więc nie jest właściwie wszystko, co użyteczne. –
To ważna kwestia. Dzięki. –
Referencje: http://docs.python.org/tutorial/modules.html#more-on-modules. http://docs.python.org/reference/simple_stmts.html#the-import-statement –