Ich habe einige Probleme bei der Strukturierung meines Python-Projekts. Momentan sind es mehrere Dateien im selben Ordner. Ich habe versucht, es wie
zu strukturieren %Vor%Das Problem ist, dass ich aus inneren Verzeichnissen keine Module aus den äußeren Verzeichnissen importieren kann. Dies ist besonders ärgerlich bei Tests.
Ich habe PEP 328 über relative Importe gelesen und PEP 366 über relative Importe aus dem Hauptmodul. Beide Methoden erfordern jedoch, dass sich das Basispaket in meinem PYTHONPATH befindet. Tatsächlich erhalte ich den folgenden Fehler
ValueError: Versuch eines relativen Imports in Nicht-Paket.
Also habe ich den folgenden Standardcode über den Testdateien hinzugefügt
%Vor%Immer noch bekomme ich den gleichen Fehler. Was ist der richtige Weg zu
? BEARBEITEN Wie im Kommentar gefordert, füge ich einen Beispielimport hinzu, der fehlschlägt (in der Datei foo_test.py
)
Wenn Sie den Code -m
zum Ausführen von Code verwenden, wird das aktuelle Verzeichnis zu sys.path
hinzugefügt. Der einfachste Weg, Ihre Tests auszuführen, ist also das übergeordnete Verzeichnis von proj
mit dem folgenden Befehl:
Damit dies funktioniert, müssen Sie eine __init__.py
-Datei in Ihr Testverzeichnis einfügen, damit die Tests korrekt als Teil des Pakets erkannt werden.
Ich möchte Module möglichst immer mit dem vollen proj.NAME
-Paket-Präfix importieren. Dies ist der Ansatz, den der Google Python-Styleguide empfiehlt.
Eine Option, die es Ihnen erlaubt, Ihre Paketstruktur beizubehalten, vollständige Paketpfade zu verwenden und trotzdem mit der Entwicklung fortzufahren, wäre, einen virtualenv zu verwenden und Ihr Projekt in den Entwicklungsmodus zu versetzen. Das setup.py
Ihres Projekts muss setuptools
anstelle von distutils
verwenden, um den Befehl develop
zu erhalten.
Damit vermeiden Sie% sys.path.append
oben:
Wo foo_test.py
verwendet:
Nun, wenn Sie python
von Ihrem virtualenv ausführen, zeigt Ihr PYTHONPATH
auf alle Pakete in Ihrem Projekt. Sie können einen kürzeren Shell-Alias erstellen, um Ihren virtualenv einzugeben, ohne jedes Mal . ~/virt/bin/activate
eingeben zu müssen.