2016-03-21 4 views
2

Es ist offensichtlich, dass die zyklischen Importfehler, wenn dieses Paket importieren:Warum ist das zyklische Importproblem verschwunden?

Datei __init__.py:

from . import modules 

Datei forward.py:

from .modules import ext_modules 

def forward(dest): 
    if dest in ext_modules: 
     print("forwarding to {}".format(ext_modules[dest])) 

Datei modules.py:

from . import forward 

ext_modules = {} 

def main(): 
    ext_modules['test'] = 'TEST' 
    forward.forward('test') 

Diese Importproblem kann z.B. indem Sie die Zeilen 1 und 3 in der Datei modules.py austauschen. Bisher glaube ich zu verstehen, was vor sich geht.

Was ich wirklich nicht verstehe, ist dies. Wenn ich einen weiteren Import an die Spitze der __init__.py Datei hinzufügen:

from . import forward 
from . import modules 

das Problem ist weg. Das Paket kann importiert werden und die Hauptfunktion funktioniert. Die Zyklusabhängigkeit zwischen modules und forward ist jedoch immer noch vorhanden. Diese Dateien bleiben unverändert. Kannst du mir bitte erklären, was dort vor sich geht? (Python-Version 3.5)

Antwort

1

Das erste, was passiert, wenn Sie ein Modul zu importieren ist, dass ein leermodule Objekt in das sys.modules Mapping hinzugefügt wird. Nachfolgende import Anweisungen für dasselbe Modul verwenden dieses Objekt erneut, anstatt die Datei in den Speicher zu laden.

Dann fährt Python mit der Ausführung des Modulinhalts fort und fügt dem module Objekt die globalen Namen hinzu, die dieser erzeugt.

In Ihrem Fall ist es wichtig, order Ihre Module importiert werden. forward hängt direkt von den Modulinhalten vonmodules, während modules nur auf dem Modul hängt forward existiert, nicht der Inhalt des Moduls (die forward.forward Referenz Abhängigkeit verschoben wird, bis main() genannt wird).

Also, wenn forward zuerst importiert wird, das leere forwardmodule Objekt erstellt wird, die erste Zeile from .modules import ext_modules ausgeführt wird, die Auslösung der die modules.py Datei geladen wird, die dann sicher Verwendung from . import forward weil dieser leermodule Objekt jetzt existiert. Der Rest der modules.py Datei kann dann ohne weiteren Vorfall weiterlaufen.

Aber wenn Sie modules zuerst importieren, dann gibt es kein forwardmodule Objekt noch, so dann die forward.py Datei zweiten Lauf, und die from .modules import ext_modules Linie schlägt fehl, da das modulesmodule Objekt noch leer ist und kein ext_modules Attribut.

+0

Vielen Dank für die ausführliche Erklärung. Ich habe es zufällig entdeckt. Ich bin mir nicht sicher, wie ich es nennen soll. Ein "leerer Modultrick" vielleicht? Wie auch immer, würdest du empfehlen, es als mögliche Lösung für das zyklische Abhängigkeitsproblem zu verwenden oder ist es eher ein hässlicher Hack? – VPfB

+1

@VPfB: Es ist eine richtige Lösung für Ihr Problem. Sie könnten es verbessern, indem Sie 'from verwenden. Importiere Module in 'forward.py', dann benutze' modules.ext_modules' im 'forward (dest)' Modul; d.h. späte Bindung überall verwenden. –