[Python] Lösen des Importproblems aufgrund der unterschiedlichen Einstiegspunkte

Bei der Ausführung vom Einstiegspunkt der Anwendung selbst, auch wenn bei der Ausführung keine Probleme auftreten Wenn ich jede Moduldatei als Einstiegspunkt startete, stolperte ich manchmal über die Importanweisung und untersuchte die Lösung.

--6 / 12: Behoben, weil außer in try ~ außer Anweisung catch war.

Der Import beginnt in dem Verzeichnis, das als Einstiegspunkt verwendet wird

Betrachten Sie als Beispiel die folgende Verzeichnis- / Dateistruktur.

main.py ...Ausführungsdatei als Anwendung
|
|--[src] ...Verzeichnis zum Speichern von Modulen
    |
    |-- module1.py ... main.Modul von py aufgerufen
    |-- module2.py ... module1.Modul von py aufgerufen

Wenn der Einstiegspunkt als Anwendung main.py ist, wird nur das Verzeichnis mit main.py als Python-Pfad erkannt. Daher müssen alle Dateien, aus denen diese Anwendung besteht, aus dem Verzeichnis importiert werden, in dem sich main.py befindet. Mit anderen Worten, wenn Sie module1.py bis module2.py in der obigen Verzeichnisstruktur verwenden möchten,

/src/module1.py


# -*- coding: utf-8 -*-

import module2 # ImportError!

Dann nein

/src/module1.py


# -*- coding: utf-8 -*-

import src.module2 # OK

Muss sein.

Es kann nicht von Dateien im src-Verzeichnis gestartet werden

Diese Beschreibung ist für den Betrieb in Ordnung, es treten jedoch Probleme beim Schreiben von Testcode in module1.py auf.

Der Testcode hier soll die Funktionsweise von Klassen und Funktionen in module1.py überprüfen. Ist es nicht üblich, einen einfachen Code zu schreiben, der eine Funktion in der Datei aufruft, und die Taste F5 zu drücken, um das Verhalten des Codes zu sehen, den Sie vor Ort geschrieben haben?

Wenn Sie jedoch "import src.module2" schreiben und das Programm mit module1.py als Einstiegspunkt starten, kann der "src" -Teil nicht erkannt werden und ein ImportError tritt auf. Dies liegt daran, dass das Ausführungsverzeichnis beim Start von module1.py in das Verzeichnis src geändert wird. Es gibt kein Verzeichnis namens "src" im src-Verzeichnis.

In diesem Artikel werde ich drei Ideen vorstellen, die dieses Problem lösen und es Ihnen ermöglichen, das Programm entweder von main.py oder module1.py aus zu starten. Übrigens haben alle Nachteile und es ist nicht in Ordnung, wenn Sie dies tun. Wir suchen nach einem intelligenteren Weg, bitte kommentieren Sie.

So sys.path.append () in der Moduldatei

Dies ist eine Lösung, indem Sie "sys.path.append ()" in module1.py schreiben. Ich denke, es ist eine ziemlich verbreitete Methode.

/src/module1.py


# -*- coding: utf-8 -*-

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
import module2

Hiermit fügen Sie das Verzeichnis mit der Datei module1.py zum Python-Pfad hinzu. Auf diese Weise wird das src-Verzeichnis zum Python-Pfad hinzugefügt, und der Fehler tritt auch dann nicht auf, wenn die import-Anweisung kein src enthält. Mit anderen Worten, Sie müssen nur "import module2" für module2.py importieren.

Diese Methode hat jedoch das Problem, dass bei einer großen Anzahl von Moduldateien die obige Beschreibung für jede Datei erforderlich ist. Außerdem wird sys.path.append () in allen Dateien mit module1.py wiedergegeben, wodurch der Namespace verschmutzt wird. (import module2 kann in main.py erstellt werden.)

So sys.path.append () mit \ _ \ _ init \ _ \ _.py

Es ist eine Methode, um \ _ \ _ init \ _ \ _. Py direkt unter dem src-Verzeichnis abzulegen und darin "sys.path.append ()" auszuführen. In diesem Fall sieht die Verzeichnisstruktur folgendermaßen aus:

main.py ...Ausführungsdatei als Anwendung
|
|--[src] ...Verzeichnis zum Speichern von Modulen
    |
    |-- __init__.py ... sys.path.append()Datei zum Ausführen
    |-- module1.py ... main.Modul von py aufgerufen
    |-- module2.py ... module1.Modul von py aufgerufen

Außerdem ist der Inhalt von \ _ \ _ init \ _ \ _. Py wie folgt.

/src/__init__.py


# -*- coding: utf-8 -*-

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))

Dies bedeutet, dass beim Importieren von src.module1 in main.py \ _ \ _ init \ _ \ _. Py ebenfalls implizit importiert wird. Insbesondere beim Ausführen von "import src.module1" aus main.py funktioniert dies so, dass \ _ \ _ init \ _ \ _. Py zuerst importiert wird und dann module1.py importiert wird. Ich werde. aus diesem Grund,

  1. Beim Importieren von \ _ \ _ init \ _ \ _. Py wird das obige sys.path.append () ausgeführt und das src-Verzeichnis zum Python-Pfad hinzugefügt.
  2. module1.py wird importiert, aber da das src-Verzeichnis bereits zum Pfad hinzugefügt wurde, kann module2.py durch Angabe von "import module2" importiert werden.

Es wird die Operation sein. Auf diese Weise können Sie die Codemenge reduzieren, da für jedes Modul im Verzeichnis src nicht "sys.path.append ()" erforderlich ist.

Solange Sie jedoch "sys.path.append ()" verwenden, bleibt das Problem der Namespace-Verschmutzung bestehen.

So fangen Sie ImportError und Branch ab

Es ist eine Methode, um ImportError abzufangen und das Importziel dynamisch zu ändern, ohne sys.path.append () zu verwenden. Insbesondere lautet der Code wie folgt.

/src/module1.py


# -*- coding: utf-8 -*-

try:
    import src.module2 # main.Wenn Sie von py ausgehen, wird dies ausgeführt
except ImportError:
    import module2 # module1.

Wenn "import src.module2" fehlschlägt, wird stattdessen "import module2" ausgeführt. Normalerweise wird die Anwendung von main.py ausgeführt, sodass Sie das Verzeichnis src im Ausführungsverzeichnis sehen können. Wenn Sie also von main.py aus starten, wird der Inhalt des try-Blocks problemlos ausgeführt.

Wenn Sie dagegen module1.py als Einstiegspunkt starten, erhalten Sie einen ImportError, da Sie das Verzeichnis src nicht sehen können. Fangen Sie daher ImportError im Ausnahmeblock ab und ändern Sie die Beschreibung des Importziels, damit es erfolgreich importiert werden kann.

Diese Technik verwendet nicht "sys.path.append ()", so dass der Namespace nicht verschmutzt wird.

Das Problem, die obige Beschreibung zu jeder Moduldatei hinzufügen zu müssen, bleibt jedoch bestehen.

Zusammenfassung

In diesem Artikel habe ich Ihnen drei Möglichkeiten gezeigt, wie Sie ein Programm entweder über main.py oder module1.py starten können.

Jede Methode hat jedoch Nachteile, daher frage ich mich, ob es notwendig ist, sie entsprechend der Umgebung richtig anzuwenden.

Recommended Posts

[Python] Lösen des Importproblems aufgrund der unterschiedlichen Einstiegspunkte
Unterschied in der Objekt-ID aufgrund des Imports in Python
Im Python-Befehl zeigt Python auf Python3.8
Finde Fehler in Python
Das 15. Offline-Echtzeit-Schreiben eines Referenzproblems in Python
Das 14. Referenzproblem beim Schreiben in Echtzeit in Python
Das 18. Offline-Echtzeit-Schreiben eines Referenzproblems in Python
Lösen Sie das maximale Subarray-Problem in Python
17. In Python implementiertes Referenzproblem für das Offline-Schreiben in Echtzeit
So ermitteln Sie mit Python den Unterschied zwischen Datum und Uhrzeit in Sekunden
Der Dateiname war in Python schlecht und ich war süchtig nach Import
Verwendung der C-Bibliothek in Python
Berechnen wir das statistische Problem mit Python
Versuchen Sie, das Problem der Python-Klassenvererbung zu lösen
Zusammenfassung zum Importieren von Dateien in Python 3
Der erste Schritt im Problem der Erfüllung von Einschränkungen in Python
Dynamisches Ersetzen der nächsten Methode in Python
Über den Unterschied zwischen "==" und "is" in Python
Zeichnen Sie Diagramme in Julia ... Überlassen Sie die Diagramme Python
Das 18. Offline-Echtzeit-Schreibproblem in Python
Tipps zum Schreiben werden in Python kurz abgeflacht
So erhalten Sie die Dateien im Ordner [Python]
Lösen von Bewegungsgleichungen in Python (odeint)
Das 19. Offline-Echtzeit-Schreibproblem in Python
Lösen Sie das Python-Rucksackproblem mit dem Greedy-Algorithmus
Ich möchte den Fortschritt in Python anzeigen!
Ich habe versucht, die in Python installierten Pakete grafisch darzustellen
So erhalten Sie den Variablennamen selbst in Python
Grundlegende Informationen Schreiben Sie das Problem mit dem Herbst 2018-Algorithmus in Python
So ermitteln Sie die Anzahl der Stellen in Python
[Python] Versuchen Sie, die coole Antwort auf das FizzBuzz-Problem zu lesen
Wie Sie das aktuelle Verzeichnis in Python in Blender kennen
Versuchen Sie, das Problem der Zuweisung von Schulungsärzten mit Python zu lösen
[Wiedereinführung in Python] Importieren über das übergeordnete Verzeichnis
Konvertieren Sie das Bild in .zip mit Python in PDF
Ich möchte nur das 95% -Konfidenzintervall des Unterschieds im Bevölkerungsverhältnis in Python ermitteln
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
Verwendung des in Lobe in Python erlernten Modells
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
[Python] So geben Sie Listenwerte der Reihe nach aus
Um das Äquivalent von Rubys ObjectSpace._id2ref in Python zu tun
Ich möchte R-Datensatz mit Python verwenden
Python Open CV hat versucht, das Bild im Text anzuzeigen.
26.12.2015 python2> datetime> Implementierung, um die Differenz in Sekunden von zwei datetime-Zeichenfolgen im ISO-Format zu ermitteln> Use .seconds ()
[Python] Wenn Sie Ihr eigenes Paket im oberen Verzeichnis importieren und verwenden möchten
[Python] So überprüfen Sie, ob der Schlüssel im Wörterbuch vorhanden ist
Geben Sie "Farn programmgesteuert zeichnen" in den Zeichenprozess in Python ein
So debuggen Sie eine Standard-Python-Bibliothek in Visual Studio
So importieren Sie die in EFS eingerichtete Python-Bibliothek in Lambda
Verwendung der Methode __call__ in der Python-Klasse
Ändern Sie das Standardausgabeziel in eine Datei in Python
So importieren Sie Dateien in Python an eine beliebige Stelle
Verschiedene Methoden zur Berechnung der Ähnlichkeit zwischen Daten mit Python
[Hinweis] Import von Dateien in das übergeordnete Verzeichnis in Python
So erhalten Sie den letzten (letzten) Wert in einer Liste in Python
Holen Sie sich das aktuelle Datum und die aktuelle Uhrzeit in Python unter Berücksichtigung des Zeitunterschieds
Ich habe versucht, die Mail-Sendefunktion in Python zu implementieren