2008-11-17 5 views
34

Wenn ein großes Modul durch ein Modul des Codes geladen wird, ist es ein Vorteil des Moduls aus diesem Namensraum zu verweisen, anstatt sie wieder zu importieren?Optimiert Python Module, wenn sie mehrfach importiert werden?

Zum Beispiel: Ich habe ein Modul MyLib, das ReallyBigLib ausgiebig nutzt. Wenn ich Code, der MyLib importiert, sollte ich das Modul ausgraben wie so

import MyLib 
ReallyBigLib = MyLib.SomeModule.ReallyBigLib 

oder nur

import MyLib 
import ReallyBigLib 

Antwort

46

Python-Module könnten als Singletons in Betracht gezogen werden ... egal, wie oft Sie importieren sie sie nur einmal initialisiert bekommen, so ist es besser zu machen:

import MyLib 
import ReallyBigLib 

Relevante Dokumentation über die Import-Anweisung:

https://docs.python.org/2/reference/simple_stmts.html#the-import-statement

Sobald der Name des Moduls bekannt ist (wenn nicht anders angegeben, wird der Begriff „Modul“ auf beiden Pakete beziehen und Module), für t suchen Das Modul oder Paket kann beginnen. Der erste überprüfte Platz ist sys.modules, der Cache aller Module, die zuvor importiert wurden. Wenn das Modul dort gefunden wird, wird es in Schritt (2) des Imports verwendet.

Dies ist ein Wörterbuch, das Modulnamen zu Modulen abbildet, die bereits geladen wurden:

Die importierten Module werden in sys.modules zwischengespeichert. Dies kann manipuliert werden, um das Nachladen von Modulen und anderen Tricks zu erzwingen. Beachten Sie, dass das Entfernen eines Moduls aus diesem Wörterbuch nicht mit dem Aufrufen von reload() für das entsprechende Modulobjekt identisch ist.

+0

Danke, Ich könnte schwören, ich habe das irgendwo gelesen, aber ich konnte es nicht finden, um zu bestätigen – JimB

+2

Wenn Sie jedoch das Modul erneut importieren möchten, können Sie die Funktion reload() verwenden. Dies könnte beispielsweise der Fall sein, wenn das Modul geändert wurde. –

+0

Ich glaube dir, aber .. kannst du auf die Dokumente zeigen? – dfrankow

0

Es ist die gleiche performancewise. In Python gibt es noch keinen JIT-Compiler.

+0

Heutzutage haben wir [PyPy] (http://pypy.org/), die ein JIT basierend auf llvm enthält. – BobC

7

Es macht keinen wesentlichen Unterschied. Wenn das große Modul bereits geladen ist, funktioniert der zweite Import in Ihrem zweiten Beispiel nichts, außer dem Hinzufügen ‚ReallyBigLib‘ auf den aktuellen Namespace.

20

Wie andere haben darauf hingewiesen, hält Python eine interne Liste aller Module, die importiert wurden. Wenn Sie ein Modul zum ersten Mal importieren, das Modul (ein Skript) in einem eigenen Namensraum bis zum Ende ausgeführt wird, wird die interne Liste aktualisiert und Ausführung weiter nach der Import-Anweisung.

Versuchen Sie diesen Code:

# module/file a.py 
    print "Hello from a.py!" 
    import b 

    # module/file b.py 
    print "Hello from b.py!" 
    import a 

Es gibt keine Schleife ist: Es gibt nur eine Cache-Suche.

>>> import b 
Hello from b.py! 
Hello from a.py! 
>>> import a 
>>> 

Eine der Schönheiten von Python ist, wie alles zufällt in einem Namespace ein Skript ausgeführt wird.

+0

Schön bewiesen :) – m93a

3

Die internen Register der importierten Module sind das sys.modules Wörterbuch, das Modulname abbildet Objekte Modul. Sie können dort nachsehen, welche Module gerade importiert werden.

Sie können auch einige nützliche Tricks (wenn Sie müssen) durch Affe mit sys.modules ziehen - zum Beispiel das Hinzufügen eigener Objekte als Pseudo-Module, die von anderen Modulen importiert werden können.

Verwandte Themen