2012-06-07 6 views
9

Ich erstelle ein Wörterbuch aus einer entfernten Datenbank als Teil meines Anwendungslaufs. Dieser Prozess ist ziemlich aufwendig, deshalb habe ich beschlossen, eine "Singleton" -Instanz dieses Wörterbuchs zu erstellen und sie so aufzurufen, wie sie in meiner Anwendung benötigt wird.Warum verhält sich ein Python-Modul wie ein Singleton?

Der Code sieht aus wie (in Dictionaries.py):

state_code_dict = None 

def get_state_code_dict(): 
    global state_code_dict 
    if state_code_dict == None: 
     state_code_dict = generate_state_code_dict() 
    return state_code_dict 

ich dann importieren und rufen die get_state_code_dict() Funktion, wo nötig. Ich fügte eine print-Anweisung hinzu, um zu überprüfen, ob state_code_dict neu initialisiert oder wiederverwendet wurde, und ich fand, dass es wiederverwendet wurde (was die Funktionalität ist, die ich möchte). Warum wird die Instanz state_code_dict überlebt die Anwendung ausgeführt?

bearbeiten

ich importieren Sie die get_state_code_dict Funktion in mehreren Dateien.

+0

weil importierter Code nur beim ersten Mal ausgeführt wird? – KurzedMetal

+0

bearbeitet, um zu verdeutlichen: Ich importiere den Code an mehreren Stellen (mehrere Dateien enthalten die 'get_state_code_dict'Funktion. –

+1

Importieren von Code, den der Interpreter bereits geladen hat, wird diesen Code nicht standardmäßig neu laden.Es ist möglich, ein Modul absichtlich neu zu laden, aber wenn Sie dies aus irgendeinem Grund tun müssen, weil sich der eigentliche Code des Moduls während der Laufzeit geändert hat, sollten Sie wahrscheinlich ein anderes Programmier-Idiom verwenden, um das zu tun, was Sie tun möchten. –

Antwort

16

Das ist die Beschreibung der Python-Sprachreferenz von how importing a module works:

(1) ein Modul finden, und initialisieren es falls erforderlich; (2) einen oder mehrere Namen in der lokalen Namensraum

(Hervorhebung hinzugefügt). Hier, Initialisierung ein Modul bedeutet, seinen Code ausführt. Diese Ausführung wird nur bei Bedarf durchgeführt, d. H. Wenn das Modul zuvor nicht in den aktuellen Prozess importiert wurde. Da es sich bei Python-Modulen um erstklassige Laufzeitobjekte handelt, werden sie zu Singletons, die zum Zeitpunkt des ersten Imports initialisiert werden.

Beachten Sie, dass dies bedeutet, dass keine get_state_dict_code Funktion benötigt wird; nur state_code_dict auf der obersten Ebene initialisieren:

state_code_dict = generate_state_code_dict() 

Für eine tiefer gehende Erklärung siehe this talk by Thomas Wouters, esp. der erste Teil - um 04.20 Uhr - wo er das Prinzip "alles ist Laufzeit" diskutiert.

+0

+1 für das vereinfachte Modul-als-Singleton-Idiom. –

+0

Würde ich dann das state_code_dict bekommen, indem ich 'import Dictionaries; state_code_dict = Wörterbücher.status_code_dict'? –

+0

@TylerDeWitt: ja. Oder mit dem idiomatischen 'from Dictionaries import state_code_dict'. –

10

Ich wählte larsmans Antwort, ich wollte nur ein Beispiel hinzufügen.

hello.py:

hi = 'hello' 

print(hi) 

def print_hi(): 
    print(hi) 

ipython Sitzung:

In [1]: from hello import print_hi 
hello 

In [2]: print_hi() 
hello 

In [3]: from hello import print_hi 

In [4]: import hello 

In [5]: hello.print_hi() 
hello 


Schauen Sie, dass die Einfuhren in den Zeilen 3 und 4 nicht ausgegeben "Hallo", wie der Import in Zeile 1, dh der Code wird nicht erneut ausgeführt.

Verwandte Themen