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?

Author: corazza, 2012-05-08

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 zmodyfikujesz foo.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 w foo - więc operacje na bar 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:

 53
Author: ThiefMaster,
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ły

Mogą 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 .

 2
Author: Darthfett,
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