Ich habe Skripte, die andere Skriptdateien aufrufen, aber ich muss den Dateipfad der Datei abrufen, die derzeit im Prozess ausgeführt wird.
Nehmen wir zum Beispiel an, ich habe drei Dateien. Mit execfile :
script_1.py
Anrufescript_2.py
.script_2.py
Anrufe wiederumscript_3.py
.
Wie kann ich die Dateinamen und den Pfad erhalten script_3.py
, von Code innerhalbscript_3.py
, ohne aus , dass die Informationen als Argument zu übergeben script_2.py
?
(Beim Ausführen wird os.getcwd()
der Dateipfad des ursprünglichen Startskripts zurückgegeben, nicht der der aktuellen Datei.)
__file__
Attribut absolut oder relativ?Antworten:
p1.py:
p2.py:
quelle
inspect.getabsfile()
beantwortet und es hat in allen Fällen funktioniert, die ich versucht habe.os.path.realpath(__file__)
wie andere gesagt haben. Möglicherweise möchten Sie auch os.path.realpath verwenden , um Symlinks zu entfernen :
quelle
__file__
'script_name.py' und manchmal 'script_name.pyc' zurückgegeben wird. Die Ausgabe ist also nicht stabil."__file__"
in Anführungszeichen (als Zeichenfolge) ausgeführt wird, wird das Verzeichnis angegeben, von dem aus cmd ausgeführt wird, aber__file__
(ohne Anführungszeichen wird der Pfad zur Quelldatei angegeben ... warum ist das soos.path.realpath
Funktion dendir
Teil des Pfads an.os.path.dirname(os.path.realpath(__file__))
Gibt das Verzeichnis mit der Datei zurück.os.path.dirname(os.path.realpath("__file__"))
gibt cwd zurück.os.path.dirname(os.path.realpath("here_be_dragons"))
gibt auch cwd zurück.Update 2018-11-28:
Hier ist eine Zusammenfassung der Experimente mit Python 2 und 3. Mit
main.py - führt foo.py aus
foo.py - führt lib / bar.py
lib / bar.py aus - druckt Dateipfadausdrücke
Für Python 2 ist es möglicherweise klarer, zu Paketen zu wechseln, um diese zu verwenden.
from lib import bar
Fügen Sie einfach leere__init__.py
Dateien zu den beiden Ordnern hinzu.Für Python 3
execfile
gibt es keine - die nächste Alternative istexec(open(<filename>).read())
, obwohl dies die Stapelrahmen betrifft. Es ist am einfachsten zu verwendenimport foo
undimport lib.bar
- keine__init__.py
Dateien erforderlich.Siehe auch Unterschied zwischen Import und Execfile
Ursprüngliche Antwort:
Hier ist ein Experiment, das auf den Antworten in diesem Thread basiert - mit Python 2.7.10 unter Windows.
Die stapelbasierten sind die einzigen, die zuverlässige Ergebnisse zu liefern scheinen. Die letzten beiden haben die kürzeste Syntax , dh -
Hier ist, dass diese als Funktionen zu sys hinzugefügt werden! Gutschrift an @Usagi und @pablog
Basierend auf den folgenden drei Dateien und Ausführen von main.py aus dem Ordner mit
python main.py
(auch Execfiles mit absoluten Pfaden ausprobiert und Aufruf aus einem separaten Ordner).C: \ Dateipfade \ main.py:
execfile('foo.py')
C: \ Dateipfade \ foo.py:
execfile('lib/bar.py')
C: \ Dateipfade \ lib \ bar.py:
quelle
Ich finde das sauberer:
und erhält die gleichen Informationen wie:
Wenn [0] der aktuelle Frame im Stapel ist (oben im Stapel) und [1] der Dateiname ist, erhöhen Sie den Wert, um im Stapel rückwärts zu gehen, d. H.
wäre der Dateiname des Skripts, das den aktuellen Frame aufgerufen hat. Wenn Sie [-1] verwenden, gelangen Sie zum Ende des Stapels, dem ursprünglichen aufrufenden Skript.
quelle
inspect.getfile()
Gibt das__file__
Attribut zurück, wenn ein Modulobjekt übergeben wurde.inspect.currentframe()
gibt das Modul zurück. Ergo ist dies eine teure Art zu sagen__file__
.inspect.stack()
ist eine ziemlich teure Funktion, mehr als nurinspect.currentframe()
, und sie ruft auchinspect.getfile()
ein Modulobjekt auf.quelle
__file__
.os.path.dirname
Sie den relativen Pfad, von dem aus Sie das Skript ausführen . zB inpython ../../test.py
deros.path.dirname
sein wird../../
und nicht der absolute Pfad zum Skript. Ich suchte nach Abspath, entfernte aber den Namen des Skripts. Das erste Element von sys.path ist anscheinend die Antwortsys.path[0]
.Die als am besten gekennzeichneten Vorschläge sind alle wahr, wenn Ihr Skript nur aus einer Datei besteht.
Wenn Sie den Namen der ausführbaren Datei (dh die Stammdatei, die für das aktuelle Programm an den Python-Interpreter übergeben wurde) aus einer Datei herausfinden möchten, die möglicherweise als Modul importiert wird, müssen Sie dies tun (nehmen wir an, dass sich diese in einer Datei befindet benannt foo.py ):
import inspect
print inspect.stack()[-1][1]
Weil das Letzte (
[-1]
) auf dem Stapel das erste ist, was hineingegangen ist (Stapel sind LIFO / FILO-Datenstrukturen).Dann in der Datei bar.py , wenn Sie
import foo
werden es drucken bar.py , anstatt foo.py , was der Wert aller von diesen sein würde:__file__
inspect.getfile(inspect.currentframe())
inspect.stack()[0][1]
quelle
sys.modules['__main__'].__file__
wirklich eine teure Art der Rechtschreibung .Dies gibt uns nur den Dateinamen. dh wenn abspath der Datei c: \ abcd \ abc.py ist, wird in der zweiten Zeile abc.py gedruckt
quelle
Es ist nicht ganz klar, was Sie unter "dem Dateipfad der Datei verstehen, die derzeit im Prozess ausgeführt wird".
sys.argv[0]
Enthält normalerweise den Speicherort des Skripts, das vom Python-Interpreter aufgerufen wurde. Überprüf denWeitere Informationen finden sys-Dokumentation .Wie @Tim und @Pat Notz hervorgehoben haben, bietet das Attribut __file__ Zugriff auf
quelle
Ich habe ein Skript, das unter Windows-Umgebung funktionieren muss. Mit diesem Code habe ich Folgendes beendet:
Es ist eine ziemlich hackige Entscheidung. Aber es erfordert keine externen Bibliotheken und es ist das Wichtigste in meinem Fall.
quelle
Versuche dies,
quelle
Keine Notwendigkeit für Inspektion oder andere Bibliothek.
Dies funktionierte für mich, als ich ein Skript (aus einem anderen Verzeichnis als dem ausgeführten Skript) importieren musste, das eine Konfigurationsdatei verwendete, die sich im selben Ordner wie das importierte Skript befand.
quelle
Das
__file__
Attribut funktioniert sowohl für die Datei mit dem Hauptausführungscode als auch für importierte Module.Siehe https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
quelle
Dies würde den Pfad des aktuell ausgeführten Skripts drucken
quelle
Ich denke, es
__file__
klingt nur so, als ob Sie auch das Inspect-Modul auschecken möchten .quelle
Sie können verwenden
inspect.stack()
quelle
Da Python 3 ziemlich Mainstream ist, wollte ich eine
pathlib
Antwort hinzufügen, da ich glaube, dass es jetzt wahrscheinlich ein besseres Werkzeug für den Zugriff auf Datei- und Pfadinformationen ist.Wenn Sie das Verzeichnis der aktuellen Datei suchen, ist es so einfach wie das Hinzufügen
.parent
zurPath()
Anweisung:quelle
quelle
Das sollte funktionieren:
quelle
quelle
Um das Verzeichnis der Ausführung des Skripts zu erhalten
quelle
Ich habe immer nur die Betriebssystemfunktion von Current Working Directory oder CWD verwendet. Dies ist Teil der Standardbibliothek und sehr einfach zu implementieren. Hier ist ein Beispiel:
quelle
python script.py
Befehl in demselben Ordner ausführen, in dem Sie sich bereits befinden. In Wirklichkeit ist es dasselbe wie unterpwd
Linux.Ich habe den Ansatz mit __file__ verwendet,
os.path.abspath(__file__)
aber es gibt einen kleinen Trick: Er gibt die .py-Datei zurück, wenn der Code zum ersten Mal ausgeführt wird. Bei den nächsten Ausführungen wird der Name * .pyc-Datei angegeben,
sodass ich bei:
inspect.getfile(inspect.currentframe())
oder blieb
sys._getframe().f_code.co_filename
quelle
Ich habe eine Funktion geschrieben, die Eclipse Debugger und Unittest berücksichtigt . Es gibt den Ordner des ersten Skripts zurück, das Sie starten. Sie können optional die Variable __file__ angeben , aber die Hauptsache ist, dass Sie diese Variable nicht für Ihre gesamte aufrufende Hierarchie freigeben müssen .
Vielleicht können Sie mit anderen Stapeln bestimmter Fälle umgehen, die ich nicht gesehen habe, aber für mich ist es in Ordnung.
quelle
Versuchen Sie Folgendes, um die Konsistenz der Migration zwischen Plattformen (macOS / Windows / Linux) zu gewährleisten:
path = r'%s' % os.getcwd().replace('\\','/')
quelle
Der einfachste Weg ist:
in script_1.py:
in script_2.py:
PS: Ich habe es versucht
execfile
, aber da es script_2.py als String liest, wurdesys.argv[0]
zurückgegeben<string>
.quelle
Hier ist, was ich verwende, damit ich meinen Code ohne Probleme überall hin werfen kann.
__name__
wird immer definiert, aber__file__
nur definiert, wenn der Code als Datei ausgeführt wird (z. B. nicht in IDLE / iPython).Alternativ kann dies wie folgt geschrieben werden:
quelle
Die meisten dieser Antworten wurden in Python Version 2.x oder früher geschrieben. In Python 3.x wurde die Syntax für die Druckfunktion dahingehend geändert, dass Klammern erforderlich sind, dh print ().
Also, diese frühere Highscore-Antwort von user13993 in Python 2.x:
Wird in Python 3.x:
quelle
Wenn Sie nur den Dateinamen ohne
./
oder möchten.py
, können Sie dies versuchenfile_name
druckt das Testskript, das Sie generieren können, indem Sie den Index in [] ändern.quelle
quelle