Ich erstelle ein einfaches Hilfsskript für die Arbeit, das einige Vorlagendateien in unserer Codebasis in das aktuelle Verzeichnis kopiert. Ich habe jedoch nicht den absoluten Pfad zu dem Verzeichnis, in dem die Vorlagen gespeichert sind. Ich habe einen relativen Pfad vom Skript, aber wenn ich das Skript aufrufe, wird dieser als Pfad relativ zum aktuellen Arbeitsverzeichnis behandelt. Gibt es eine Möglichkeit anzugeben, dass diese relative URL stattdessen vom Speicherort des Skripts stammt?
python
relative-path
path
Baudtack
quelle
quelle
Antworten:
In der Datei mit dem Skript möchten Sie Folgendes tun:
Dadurch erhalten Sie den absoluten Pfad zu der gesuchten Datei. Beachten Sie, dass Sie bei Verwendung von setuptools wahrscheinlich stattdessen die Paketressourcen- API verwenden sollten.
UPDATE : Ich antworte hier auf einen Kommentar, damit ich ein Codebeispiel einfügen kann. :-)
Ich gehe davon aus, dass Sie das
__main__
Skript meinen, wenn Sie erwähnen, dass die Datei direkt ausgeführt wird. Wenn ja, scheint dies auf meinem System nicht der Fall zu sein (Python 2.5.1 unter OS X 10.5.7):Ich weiß jedoch, dass es einige Macken bei
__file__
C-Erweiterungen gibt. Zum Beispiel kann ich dies auf meinem Mac tun:Dies löst jedoch eine Ausnahme auf meinem Windows-Computer aus.
quelle
filename = os.path.join(dir, 'relative', 'path', 'to', 'file', 'you' , 'want')
os.path.dirname(__file__)
kann eine leere Zeichenfolge geben, verwenden Sieos.path.dirname(os.path.abspath(__file__))
stattdessenSie benötigen
os.path.realpath
(Beispiel unten fügt das übergeordnete Verzeichnis zu Ihrem Pfad hinzu)quelle
os.path.dirname(__file__)
gab mir eine leere Schnur. Das hat perfekt funktioniert.os.path.realpath('..')
gibt Ihnen das übergeordnete Verzeichnis des aktuellen Arbeitsverzeichnisses . Das ist normalerweise nicht das, was du willst.Wie in der akzeptierten Antwort erwähnt
Ich möchte das nur hinzufügen
Es sollte so etwas wie sein
Die akzeptierte Antwort kann in einigen Fällen irreführend sein. Weitere Informationen finden Sie unter diesem Link
quelle
os.path.join
ist besser, da sie mit dem betriebssystemspezifischen Trennzeichen verbunden werden.'/relative/path...'
ist kein relativer Pfad. Ist das beabsichtigt?os.path.join()
. Was bleibt, ist die Präferenz, separate Zeichenfolgen für jedes Pfadelement zu verwenden, anstatt das Pfadtrennzeichen fest zu codieren.Es ist jetzt 2018 und Python hat sich bereits vor
__future__
langer Zeit weiterentwickelt. So wie über die erstaunliche Verwendungpathlib
mit Python 3.4 kommt die Aufgabe zu erfüllen , anstatt mit zu kämpfenos
,os.path
,glob
,shutil
etc.Wir haben hier also 3 Pfade (möglicherweise dupliziert):
mod_path
: Dies ist der Pfad des einfachen Hilfsskriptssrc_path
: enthält einige Vorlagendateien, die darauf warten, kopiert zu werden.cwd
: aktuelles Verzeichnis , das Ziel dieser Vorlagendateien.und das Problem ist: Wir haben nicht den vollständigen Pfad von
src_path
, wissen nur, dass es der relative Pfad zum istmod_path
.Lassen Sie uns dies nun mit dem Erstaunlichen lösen
pathlib
:In Zukunft ist es so einfach. : D.
Darüber hinaus können wir diese Vorlagendateien auswählen, überprüfen und kopieren / verschieben mit
pathlib
:quelle
Betrachten Sie meinen Code:
quelle
Siehe sys.path Wie beim Programmstart initialisiert, ist das erste Element dieser Liste, Pfad [0], das Verzeichnis, das das Skript enthält, mit dem der Python-Interpreter aufgerufen wurde.
Verwenden Sie diesen Pfad als Stammordner, aus dem Sie Ihren relativen Pfad anwenden
quelle
sys.path[0]
wird nicht immer auf das übergeordnete Verzeichnis gesetzt. Python-Code kann mit-c
oder-m
über einen eingebetteten Interpreter aufgerufen werden. An diesem Punktsys.path[0]
wird ein ganz anderer Wert festgelegt.Anstatt zu verwenden
Wie in der akzeptierten Antwort wäre es robuster zu verwenden:
Da die Verwendung von __file__ die Datei zurückgibt, aus der das Modul geladen wurde, wenn es aus einer Datei geladen wurde. Wenn also die Datei mit dem Skript von einer anderen Stelle aufgerufen wird, ist das zurückgegebene Verzeichnis nicht korrekt.
Diese Antworten enthalten weitere Details: https://stackoverflow.com/a/31867043/5542253 und https://stackoverflow.com/a/50502/5542253
quelle
inspect.stack()
ist eine teure Funktion zum Aufrufen. Es ruft Informationen für alle Stapelrahmen ab, die Sie dann verwerfen und nur den obersten für erhalten. Grundsätzlich wirdinspect.getfile()
das Modulobjekt aufgerufen, das gerade zurückgegeben wirdmodule.__file__
. Sie sind viel besser darin, nur zu verwenden__file__
.Hallo, zuerst sollten Sie die Funktionen os.path.abspath (Pfad) und os.path.relpath (Pfad) verstehen.
Kurz gesagt, os.path.abspath (Pfad) erstellt einen relativen Pfad zum absoluten Pfad . Und wenn der angegebene Pfad selbst ein absoluter Pfad ist, gibt die Funktion denselben Pfad zurück.
In ähnlicher Weise erstellt os.path.relpath (Pfad) einen absoluten Pfad zum relativen Pfad . Wenn der angegebene Pfad selbst ein relativer Pfad ist, gibt die Funktion denselben Pfad zurück.
Mit dem folgenden Beispiel können Sie das obige Konzept richtig verstehen :
Angenommen, ich habe eine Datei input_file_list.txt, die eine Liste der Eingabedateien enthält, die von meinem Python-Skript verarbeitet werden sollen.
D: \ conc \ input1.dic
D: \ conc \ input2.dic
D: \ Copyioconc \ input_file_list.txt
Wenn Sie über Ordnerstruktur sehen, input_file_list.txt in Gegenwart ist Copyofconc Ordner und Dateien , die von dem Python - Skript verarbeitet werden sollen , die in Konz Ordner
Der Inhalt der Datei input_file_list.txt ist jedoch wie folgt :
.. \ conc \ input1.dic
.. \ conc \ input2.dic
Und mein Python-Skript ist in Laufwerk D: vorhanden .
Der in der Datei input_file_list.txt angegebene relative Pfad ist relativ zum Pfad der Datei input_file_list.txt .
Wenn das Python-Skript das aktuelle Arbeitsverzeichnis ausführen soll (verwenden Sie os.getcwd () , um den Pfad abzurufen ).
Da mein relativer Pfad ist relativ zu input_file_list.txt , das heißt „D: \ Copyofconc“ , ich habe das aktuelle Arbeitsverzeichnis ändern „D: \ Copyofconc“ .
Also muss ich os.chdir ('D: \ Copyofconc') verwenden , damit das aktuelle Arbeitsverzeichnis "D: \ Copyofconc" ist .
Um nun die Dateien input1.dic und input2.dic zu erhalten , lese ich die Zeilen ".. \ conc \ input1.dic" und verwende dann den Befehl
input1_path = os.path.abspath ('.. \ conc \ input1.dic') (um den relativen Pfad in den absoluten Pfad zu ändern. Hier lautet das aktuelle Arbeitsverzeichnis "D: \ Copyofconc", die Datei ". \ conc \ input1. Auf dic "wird relativ zu" D: \ Copyofconc "zugegriffen.
so input1_path wird "D: \ Konz \ input1.dic"
quelle
Dieser Code gibt den absoluten Pfad zum Hauptskript zurück.
Dies funktioniert auch in einem Modul.
quelle
sys.modules['__main__'].__file__
.Eine Alternative, die für mich funktioniert:
quelle
Was für mich funktioniert hat, ist mit
sys.path.insert
. Dann gab ich das Verzeichnis an, in das ich gehen musste. Zum Beispiel musste ich nur ein Verzeichnis hochgehen.quelle
Ich bin nicht sicher, ob dies für einige der älteren Versionen gilt, aber ich glaube, dass Python 3.3 native Unterstützung für relative Pfade bietet.
Der folgende Code sollte beispielsweise eine Textdatei im selben Ordner wie das Python-Skript erstellen:
(Beachten Sie, dass es am Anfang keinen Vorwärts- oder Rückwärtsschlag geben sollte, wenn es sich um einen relativen Pfad handelt.)
quelle