Ein anderer Entwickler und ich sind uns nicht einig, ob PYTHONPATH oder sys.path verwendet werden sollen, damit Python ein Python-Paket in einem Benutzerverzeichnis (z. B. Entwicklungsverzeichnis) finden kann.
Wir haben ein Python-Projekt mit einer typischen Verzeichnisstruktur:
Project
setup.py
package
__init__.py
lib.py
script.py
In script.py müssen wir tun import package.lib
. Wenn das Paket in Site-Paketen installiert ist, kann script.py finden package.lib
.
Bei der Arbeit in einem Benutzerverzeichnis muss jedoch noch etwas anderes getan werden. Meine Lösung besteht darin, meinen PYTHONPATH so einzustellen, dass er "~ / Project" enthält. Ein anderer Entwickler möchte diese Codezeile am Anfang von script.py einfügen:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Damit Python die lokale Kopie von finden kann package.lib
.
Ich denke, dies ist eine schlechte Idee, da diese Zeile nur für Entwickler oder Leute nützlich ist, die mit einer lokalen Kopie arbeiten, aber ich kann keinen guten Grund nennen, warum es eine schlechte Idee ist.
Sollten wir PYTOHNPATH, sys.path oder entweder in Ordnung verwenden?
quelle
Antworten:
Wenn der einzige Grund für die Änderung des Pfads darin besteht, dass Entwickler von ihrem Arbeitsbaum aus arbeiten, sollten Sie ein Installationstool verwenden, um Ihre Umgebung für Sie einzurichten. virtualenv ist sehr beliebt. Wenn Sie setuptools verwenden, können Sie
setup.py develop
den Arbeitsbaum in Ihrer aktuellen Python-Installation einfach halb installieren.quelle
Ich hasse PYTHONPATH. Ich finde es spröde und ärgerlich, auf Benutzerbasis (insbesondere für Daemon-Benutzer) festzulegen und zu verfolgen, wie sich Projektordner bewegen. Ich würde viel lieber
sys.path
in den Aufrufskripten für eigenständige Projekte setzen.Dies
sys.path.append
ist jedoch nicht der richtige Weg. Sie können leicht Duplikate erhalten, und es werden keine.pth
Dateien sortiert . Besser (und besser lesbar) :site.addsitedir
.Und
script.py
wäre normalerweise nicht der geeignetere Ort dafür, da es sich innerhalb des Pakets befindet, das Sie auf dem Pfad verfügbar machen möchten. Bibliotheksmodule sollten sich auf keinen Fallsys.path
selbst berühren . Stattdessen haben Sie normalerweise ein Hashbanged-Skript außerhalb des Pakets, mit dem Sie die App instanziieren und ausführen. In diesem trivialen Wrapper-Skript würden Sie Bereitstellungsdetails wiesys.path
-frobbing einfügen.quelle
site.addsitedir
ist , dass es funktioniertappend
aufsys.path
, was bedeutet , dass ein installierte Paket Vorrang vor dem lokalen Paket in der Entwicklung stattfinden wird (und Haare ziehen erfolgen können).sys.path.insert(0...
wird benötigt, um das zu überwinden.sys.path.insert(1
. stackoverflow.com/q/10095037/125507Im Allgemeinen würde ich das Einrichten einer Umgebungsvariablen (wie PYTHONPATH) als schlechte Praxis betrachten. Während dies für ein einmaliges Debugging in Ordnung sein mag, ist es
möglicherweise keine gute Idee , dies als reguläre Übung zu verwenden.
Die Verwendung von Umgebungsvariablen führt zu Situationen wie "es funktioniert für mich", wenn
jemand anderes Probleme in der Codebasis meldet. Dies kann auch in der Testumgebung der Fall sein, was dazu führt, dass die Tests für einen bestimmten Entwickler einwandfrei laufen, aber wahrscheinlich fehlschlagen, wenn jemand die Tests startet.
quelle
Ich denke, dass in diesem Fall die Verwendung von PYTHONPATH eine bessere Sache ist, hauptsächlich weil es keinen (fragwürdigen) unnötigen Code einführt.
Wenn Sie daran denken, braucht Ihr Benutzer das
sys.path
Ding schließlich nicht, weil Ihr Paket in Site-Paketen installiert wird, weil Sie ein Verpackungssystem verwenden.Wenn der Benutzer eine "lokale Kopie" ausführt, wie Sie sie nennen, habe ich festgestellt, dass die übliche Praxis darin besteht, anzugeben, dass das Paket manuell zu PYTHONPATH hinzugefügt werden muss, wenn es außerhalb der Site-Pakete verwendet wird .
quelle
Zusammen mit den vielen anderen bereits erwähnten Gründen könnten Sie auch auf diese Hardcodierung hinweisen
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
ist spröde, weil es den Speicherort von script.py voraussetzt - es funktioniert nur, wenn sich script.py in Project / package befindet. Es wird unterbrochen, wenn ein Benutzer beschließt, script.py (fast) an eine andere Stelle zu verschieben / kopieren / symlink.
quelle
Weder Hacking
PYTHONPATH
nochsys.path
ist aus den oben genannten Gründen eine gute Idee. Und um das aktuelle Projekt mit dem Site-Packages-Ordner zu verknüpfen, gibt es tatsächlich einen besseren Weg alspython setup.py develop
, wie hier erklärt :pip install --editable path/to/project
Wenn Sie noch keine setup.py im Stammordner Ihres Projekts haben, ist diese gut genug, um damit zu beginnen:
quelle