Jak dokładnie działa Importowanie Pythona?
Mam dwie konkretne sytuacje, w których nie rozumiem, jak działa importowanie w Pythonie:
1. sytuacja szczególna:
Kiedy importuję ten sam moduł do dwóch różnych skryptów Pythona, moduł nie jest importowany dwa razy, prawda? Python po raz pierwszy napotka go, jest importowany, a po raz drugi, czy sprawdza, czy moduł został zaimportowany, czy robi kopię?
2. sytuacja szczególna:
Rozważmy następujący moduł, zwany bla.py
:
a = 10
I mamy foo.py
, moduł importujący bla.py
:
from bla import *
def Stuff ():
return a
I po tym mamy skrypt o nazwie bar.py
, który jest wykonywany przez użytkownika:
from foo import *
Stuff() #This should return 10
a = 5
Stuff()
Tutaj Nie wiem: czy Stuff()
zwraca 10 czy 5?
2 answers
Część 1
Moduł jest ładowany tylko raz, więc nie ma utraty wydajności po ponownym zaimportowaniu go. Jeśli chcesz, aby został załadowany/przetworzony ponownie, musisz reload()
moduł.
Pierwszym sprawdzonym miejscem jest
sys.modules
, Pamięć podręczna wszystkich modułów, które zostały wcześniej zaimportowane. [źródło]
Część 2
from foo import *
IMPORT a
do zakresu lokalnego. Przy przypisywaniu wartości a
, to zostanie zastąpiona nową wartością-ale oryginalna zmienna foo.a
nie zostanie dotknięta.
Więc jeśli nie zmodyfikujesz import foo
i foo.a
, oba wywołania zwrócą tę samą wartość.
Dla zmiennego typu, takiego jak list lub dict, byłoby inaczej, modyfikowanie go rzeczywiście wpłynęłoby na pierwotną zmienną - ale przypisanie jej nowej wartości nadal nie zmieniłoby foo.whatever
.
Jeśli chcesz uzyskać bardziej szczegółowe informacje, zajrzyj do http://docs.python.org/reference/executionmodel.html :
Następujące konstrukcje wiążą nazwy: parametry formalne do funkcji, import instrukcji , definicje klas i funkcji (te wiążą nazwę klasy lub funkcji w bloku definiującym) oraz cele , które są identyfikatorami, jeśli występują w przypisaniu, dla nagłówka pętli, na drugiej pozycji nagłówka klauzuli except lub po instrukcji with.
The two bold sekcje są odpowiednie dla Ciebie: najpierw Nazwa a
jest związana z wartością foo.a
podczas importu. Następnie, wykonując a = 5
, Nazwa a
jest związana z 5
. Ponieważ modyfikowanie listy/dict nie powoduje wiązania, operacje te spowodowałyby modyfikację oryginalnej (b
i foo.b
są powiązane z tym samym obiektem, na którym operujesz). Przypisanie nowego obiektu do b
byłoby ponownie operacją wiążącą i tym samym oddzieleniem b
od foo.b
.
Warto również zwrócić uwagę na to, co dokładnie to import
stwierdzenie robi:
-
import foo
wiąże nazwę modułu z obiektem module w bieżącym zakresie, więc jeśli zmodyfikujeszfoo.whatever
, będziesz pracować z nazwą w tym module - wszelkie modyfikacje / przypisania będą miały wpływ na zmienną w module. -
from foo import bar
wiąże tylko podaną nazwę (tzn.foo
pozostanie niezwiązana) z elementem o tej samej nazwie wfoo
- więc operacje nabar
zachowują się tak, jak wyjaśniono wcześniej. -
from foo import *
zachowuje się jak poprzednie jeden, ale importuje wszystkie nazwy globalne, które nie są poprzedzone podkreśleniem. Jeśli moduł definiuje__all__
, importowane są tylko nazwy wewnątrz tej sekwencji.
Część 3 (która nawet nie istnieje w twoim pytaniu: p)
Dokumentacja Pythona jest bardzo dobra i zwykle mówiona - znajdziesz tam odpowiedź na prawie każde możliwe pytanie związane z językiem. Oto kilka przydatnych linki:
- http://docs.python.org/reference/datamodel.html (klasy, właściwości, metody magiczne itp.) ()
-
http://docs.python.org/reference/executionmodel.html jak działają zmienne w Pythonie?]}
- http://docs.python.org/reference/expressions.html
- http://docs.python.org/reference/simple_stmts.html (wypowiedzi takie jak
import
,yield
)- http://docs.python.org/reference/compound_stmts.html (polecenia blokowe takie jak
for
,try
,with
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-08 15:57:34
Aby odpowiedzieć na pierwsze pytanie:
Nie, python nie jest 'importowany' dwa razy. Gdy python ładuje moduł, sprawdza czy moduł jest w sys.modules
. Jeśli go tam nie ma, wkłada się go tam i ładuje.
Aby odpowiedzieć na drugie pytanie:
ModułyMogą definiować nazwy, które będą eksportowane do scenariusza from camelot import *
, A zachowanie polega na tworzeniu nazw dla istniejących wartości, a nie odwoływaniu się do istniejących zmiennych (python nie ma referencji).
On a nieco pokrewny temat, Robienie from camelot import *
jest nie tym samym, co zwykły import .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-08 15:54:43