Eine ähnliche Antwort habe ich auch auf die Frage nach Importen aus Geschwisterpaketen gegeben. Sie können es sehen aquí .
Lösung ohne sys.path
Hacks
Zusammenfassung
- Packen Sie den Code in einen Ordner (z. B.
packaged_stuff
)
- Erstellen einer
setup.py
Skript, in dem Sie Folgendes verwenden setuptools.setup() .
- Pip installiert das Paket im bearbeitbaren Zustand mit
pip install -e <myproject_folder>
- Importieren mit
from packaged_stuff.modulename import function_name
Einrichtung
Ich gehe von der gleichen Ordnerstruktur wie in der Frage aus
.
ptdraft
__init__.py
nib.py
simulations
__init__.py
life
__init__.py
life.py
Ich rufe die .
den Root-Ordner, und in meinem Fall befindet er sich in C:\tmp\test_imports
.
Schritte
-
Hinzufügen einer setup.py
in den Root-Ordner -- Der Inhalt des Ordners setup.py
kann einfach sein
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
Im Grunde genommen "jeder" setup.py
funktionieren würde. Dies ist nur ein minimales Arbeitsbeispiel.
- Verwenden Sie eine virtuelle Umgebung
Wenn Sie mit virtuellen Umgebungen vertraut sind, aktivieren Sie eine und fahren Sie mit dem nächsten Schritt fort. Die Nutzung von virtuellen Umgebungen ist nicht absolut erforderlich, aber sie werden wirklich Ihnen auf lange Sicht helfen (wenn Sie mehr als 1 Projekt haben ). Die grundlegendsten Schritte sind (im Stammordner ausgeführt)
- Virtuelle Umgebung erstellen
- Virtuelle Umgebung aktivieren
. venv/bin/activate
(Linux) oder ./venv/Scripts/activate
(Sieg)
- Deaktivieren der virtuellen Umgebung
Um mehr darüber zu erfahren, googeln Sie einfach nach "python virtualenv tutorial" oder ähnlichem. Wahrscheinlich brauchen Sie nie andere Befehle als das Erstellen, Aktivieren und Deaktivieren.
Sobald Sie eine virtuelle Umgebung erstellt und aktiviert haben, sollte Ihre Konsole den Namen der virtuellen Umgebung in Klammern anzeigen
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
- Pip-Installation Ihres Projekts im bearbeitbaren Zustand
Installieren Sie Ihr Top-Level-Paket myproject
mit pip
. Der Trick besteht darin, die -e
Flagge, wenn Sie die Installation durchführen. Auf diese Weise wird es in einem bearbeitbaren Zustand installiert, und alle an den .py-Dateien vorgenommenen Änderungen werden automatisch in das installierte Paket aufgenommen.
Führen Sie im Root-Verzeichnis
pip install -e .
(beachten Sie den Punkt, er steht für "aktuelles Verzeichnis")
Sie können auch sehen, dass es installiert ist, indem Sie pip freeze
(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0
- Importieren durch Voranstellen von
mainfolder
zu jeder Einfuhr
In diesem Beispiel ist die mainfolder
wäre ptdraft
. Dies hat den Vorteil, dass es nicht zu Namenskollisionen mit anderen Modulnamen (aus der Python-Standardbibliothek oder Modulen von Drittanbietern) kommt.
Beispiel für die Verwendung
nib.py
def function_from_nib():
print('I am the return value from function_from_nib!')
Leben.py
from ptdraft.nib import function_from_nib
if __name__ == '__main__':
function_from_nib()
Leben.py ausführen
(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!
1 Stimmen
Wie ist Ihr PYTHONPATH eingestellt?
2 Stimmen
Ross: Ich habe es mir angesehen. Was soll ich dagegen tun? Ich habe bereits eine
__init__.py
. S.Lott: Ich weiß nicht, wie ich das überprüfen kann...4 Stimmen
Echo $PYTHONPATH aus der Shell; import sys; print sys.path aus Python heraus. docs.python.org/tutorial/
0 Stimmen
@FlipMcF Google ist eine Suchmaschine mit Blasen, daher spielt es keine Rolle, dass dieses Ergebnis für Sie ziemlich weit oben steht. Viel wichtiger ist die Tatsache, dass die nicht geblubberte Suchmaschine, DuckDuckGo, dieses Ergebnis ebenfalls sehr hoch einstuft.
0 Stimmen
@FlipMcF Es ist nichts falsch daran, einen absoluten Import wie in der Antwort von Hasen zu machen. Das wird in Django hunderte Male gemacht. Es ist absolut akzeptabel. In manchen Fällen ist ein relativer Import schöner und kürzer, also können Sie diese Methoden ruhig austauschbar verwenden.
0 Stimmen
@RamRachum Meine Meinung hat sich inzwischen zu Absolute Imports geändert. Relative Importe sind nett, aber "Explicit ist besser als Implicit" und in geringerem Maße "Namespaces sind eine großartige Idee".
0 Stimmen
@FlipMcF aber ich habe gehört, dass relative Importe als schlechtes Verhalten angesehen werden?
1 Stimmen
Werfen Sie einen Blick auf diesen endgültigen Leitfaden chrisyeh96.github.io/2017/08/08/…
20 Stimmen
Ich empfehle dringend, alles zu überspringen
sys.path
oPYTHONPATH
Antworten und Auschecken np8s ausgezeichnete Antwort . Ja, es ist eine lange Lektüre. Ja, es sieht nach einer Menge Arbeit aus. Aber es ist die einzige Lösung, die das Problem tatsächlich korrekt und sauber löst.9 Stimmen
Was ist aus dem ausführbaren Pseudocode geworden? Warum ist es so mühsam, Module aus einem übergeordneten Ordner in Python zu importieren? Das ist absurd.
2 Stimmen
@eric: Es ist nur dann schwierig, wenn Sie inkonsequent sind: Sie verwenden ein Dateilayout, das zu einem Paket (eine komplizierte, wiederverwendbare Bibliothek, von der Ihr Skript nur ein Client ist), aber der Versuch, es als Wegwerfprogramm auszuführen Skript (auch ohne
python -m
).15 Stimmen
Warum ist das so ein Problem? Nachdem ich alle Diskussionen und Antworten durchgelesen habe, gibt es immer noch keine vernünftige, einfache Lösung.
1 Stimmen
Ich behaupte, dass tjk's Antwort ist die einfachste und pythonischste. Wenn Sie eine Python-Funktion erstellen, die andere Dateien importiert, schreiben Sie keine einmaligen Skripte, so dass Ihre "Skriptdateien" eigentlich nur Moduldateien sind, und obwohl Sie sie als Skriptdateien ausführen können, wird dies eher als eine zusätzliche Funktion in die Dokumentation als die "richtige" Art, sie zu betreiben.
0 Stimmen
@ApollyssupportsMonica Es gibt keinen Schmerz. Wenn du Code von außerhalb des Pakets direkt importieren möchtest, aktualisierst du einfach die
sys.path
. Daran ist nichts schwierig oder hakelig. Beachten Sie, dass der Standardweg darin besteht, keinen externen Code direkt zu importieren, sondern diesen Code als Abhängigkeit zu installieren, indem Sie diepip
Werkzeug.