Hier ist eine Antwort, die einfach ist, damit Sie sehen können, wie sie funktioniert, klein und plattformübergreifend.
Es verwendet nur eingebaute Module ( os
, sys
et inspect
), sollte also funktionieren
auf jedem Betriebssystem (OS), da Python dafür ausgelegt ist.
Kürzerer Code für die Antwort - weniger Zeilen und Variablen
from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module # Replace "my_module" here with the module name.
sys.path.pop(0)
Für weniger Zeilen als diese, ersetzen Sie die zweite Zeile durch import os.path as path, sys, inspect
,
add inspect.
zu Beginn von getsourcefile
(Zeile 3) und entfernen Sie die erste Zeile.
- Allerdings werden dabei alle Module importiert, so dass mehr Zeit, Speicher und Ressourcen benötigt werden könnten.
Der Code für meine Antwort ( längere Version )
from inspect import getsourcefile
import os.path
import sys
current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]
sys.path.insert(0, parent_dir)
import my_module # Replace "my_module" here with the module name.
Sie verwendet ein Beispiel aus einer Stack Overflow-Antwort Wie erhalte ich den Pfad des aktuellen
Datei in Python ausführen? um die Quelle (Dateiname) von laufendem Code mit einem eingebauten Werkzeug zu finden.
from inspect import getsourcefile
from os.path import abspath
Als Nächstes können Sie die Quelldatei überall dort finden, wo Sie sie haben möchten:
abspath(getsourcefile(lambda:0))
Mein Code fügt einen Dateipfad zu sys.path
は、その python pfadliste
weil dies Python erlaubt, Module aus diesem Ordner zu importieren.
Nach dem Importieren eines Moduls in den Code ist es eine gute Idee, die Funktion sys.path.pop(0)
in einer neuen Zeile
wenn der hinzugefügte Ordner ein Modul mit demselben Namen wie ein anderes importiertes Modul enthält
später im Programm. Sie müssen das vor dem Import hinzugefügte Listenelement entfernen, nicht andere Pfade.
Wenn Ihr Programm keine anderen Module importiert, ist es sicher, den Dateipfad nicht zu löschen, weil
nach dem Beenden eines Programms (oder dem Neustart der Python-Shell), werden alle Änderungen, die an sys.path
verschwinden.
Hinweise zu einer Dateinamen-Variable
Meine Antwort verwendet nicht die __file__
um den Dateipfad/Dateinamen der laufenden
Code, denn die Nutzer hier haben ihn oft beschrieben als unzuverlässig . Sie sollten es nicht verwenden
für Module aus übergeordnetem Ordner importieren in Programmen, die von anderen Personen verwendet werden.
Einige Beispiele, wo es nicht funktioniert (Zitat aus ce Stack Overflow-Frage):
- es kann nicht sein auf einigen Plattformen zu finden - manchmal nicht der vollständige Dateipfad ist
py2exe
hat keine __file__
Attribut, aber es gibt eine Umgehung
- Wenn Sie von IDLE aus mit
execute()
Es gibt keine __file__
Attribut
- OS X 10.6, wo ich Folgendes erhalte
NameError: global name '__file__' is not defined
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.