Ich versuche, den Namen des Python-Skripts zu ermitteln, das gerade ausgeführt wird.
Ich habe ein Skript namens foo.py
und möchte so etwas tun, um den Skriptnamen zu erhalten:
print Scriptname
Sie können verwenden __file__
, um den Namen der aktuellen Datei abzurufen. Bei Verwendung im Hauptmodul ist dies der Name des Skripts, das ursprünglich aufgerufen wurde.
Wenn Sie den Verzeichnisteil (der möglicherweise vorhanden ist) weglassen möchten, können Sie ihn verwenden os.path.basename(__file__)
.
Exception NameError: NameError("global name '__file__' is not defined",)
"__file__
ist im interaktiven Interpreter nicht definiert, da es dort bedeutungslos ist. Es wird von der Importimplementierung festgelegt. Wenn Sie also einen nicht standardmäßigen Importmechanismus verwenden, wird dieser möglicherweise auch nicht festgelegt.import os
erforderlich ist, damit dies funktioniert. Ich würde dies in die Antwort aufnehmen.import os
undimport os.path
sind völlig gleichwertig.Dies wird
foo.py
fürpython foo.py
,dir/foo.py
fürpython dir/foo.py
usw. gedruckt . Es ist das erste Argument dafürpython
. (Beachten Sie, dass es nach py2exe sein würdefoo.exe
.)quelle
python linkfile.py
, wolinkfile.py
ist ein Symlink zurealfile.py
,sys.argv[0]
wird'linkfile.py'
, was kann oder kann nicht sein, was Sie wollen; es ist sicherlich das, was ich erwarte .__file__
ist das gleiche: es wird seinlinkfile.py
. Wenn Sie wissen wollen ,'realfile.py'
aus'linkfile.py'
, versuchenos.path.realpath('linkfile.py')
.__file__
sondern stattdessen.Der Vollständigkeit halber hielt ich es für sinnvoll, die verschiedenen möglichen Ergebnisse zusammenzufassen und Referenzen für das genaue Verhalten der einzelnen zu liefern:
__file__
ist die aktuell ausgeführte Datei, wie in der offiziellen Dokumentation beschrieben :Von Python3.4 ab, pro Ausgabe 18.416 ,
__file__
ist immer ein absoluter Pfad, es sei denn , die aktuell ausgeführte Datei ist ein Skript , das direkt (mit der nicht über den Interpreter ausgeführt wurde-m
unter Verwendung eines relativen Pfadbefehlszeilenoption).__main__.__file__
(muss importiert werden__main__
) greift einfach auf das oben genannte__file__
Attribut des Hauptmoduls zu , z. B. des Skripts, das über die Befehlszeile aufgerufen wurde.sys.argv[0]
(muss importiert werdensys
) ist der Skriptname, der über die Befehlszeile aufgerufen wurde und möglicherweise ein absoluter Pfad ist, wie in der offiziellen Dokumentation beschrieben :Wie in einer anderen Antwort auf diese Frage erwähnt , zeigen Python- Skripte, die über Tools wie py2exe oder PyInstaller in eigenständige ausführbare Programme konvertiert wurden, bei Verwendung dieses Ansatzes möglicherweise nicht das gewünschte Ergebnis an (dh
sys.argv[0]
sie enthalten eher den Namen der ausführbaren Datei als den Namen der Python- Hauptdatei in dieser ausführbaren Datei).Wenn keine der oben genannten Optionen zu funktionieren scheint, wahrscheinlich aufgrund eines unregelmäßigen Importvorgangs, kann sich das Inspektionsmodul als nützlich erweisen. Insbesondere könnte das Aufrufen von
inspect.getfile(...)
oninspect.currentframe()
funktionieren, obwohl letzteres zurückkehren würde ,None
wenn es in einer Implementierung ohne Python- Stack-Frame ausgeführt wird.Umgang mit symbolischen Links
Wenn das aktuelle Skript eine symbolische Verknüpfung ist, geben alle oben genannten Elemente den Pfad der symbolischen Verknüpfung und nicht den Pfad der realen Datei zurück und
os.path.realpath(...)
sollten aufgerufen werden, um letztere zu extrahieren.Weitere Manipulationen, die den tatsächlichen Dateinamen extrahieren
os.path.basename(...)
kann auf einem der oben genannten Punkte aufgerufen werden, um den tatsächlichen Dateinamen zu extrahieren, undos.path.splitext(...)
kann auf dem tatsächlichen Dateinamen aufgerufen werden, um sein Suffix wie in abzuschneidenos.path.splitext(os.path.basename(...))
.Ab Python 3.4 kann gemäß PEP 428 die
PurePath
Klasse despathlib
Moduls auch für alle oben genannten Zwecke verwendet werden. Insbesonderepathlib.PurePath(...).name
extrahiert die tatsächlichen Dateinamen undpathlib.PurePath(...).stem
extrahiert die tatsächlichen Dateinamen ohne seine Suffix.quelle
Beachten Sie,
__file__
dass die Datei, in der sich dieser Code befindet, importiert werden kann und sich von der zu interpretierenden Hauptdatei unterscheidet. Um die Hauptdatei zu erhalten, kann das spezielle Modul __main__ verwendet werden:Beachten Sie, dass dies
__main__.__file__
in Python 2.7 funktioniert, jedoch nicht in 3.2. Verwenden Sie daher die oben beschriebene Import-as-Syntax, um es portabel zu machen.quelle
rPython
Paket aus derR
Sprache verwende. Das muss ein Ausnahmefall sein, der einfach zu schwer zu handhaben ist.__main__
intern importiert , um Variablen zwischenR
und zu übergebenpython
. Daher wäre es relativ einfach, es__main__.__file__
vor dem Aufrufen von etwas anderem festzulegen, aber ich bin mir nicht einmal sicher, welcher Wert in diesem Fall angemessen wäre.Die obigen Antworten sind gut. Aber ich fand diese Methode unter Verwendung der obigen Ergebnisse effizienter.
Dies führt dazu, dass der tatsächliche Name der Skriptdatei kein Pfad ist.
quelle
Für moderne Python-Versionen (3.4+)
Path(__file__).name
sollte idiomatischer sein. AußerdemPath(__file__).stem
haben Sie die Skriptnamen ohne die.py
Erweiterung.quelle
from pathlib import Path
zuerst.pathlib
wurde in Python 3.4 eingeführt, daher sollte es ab Python 3.4 funktionieren.Versuche dies:
quelle
Hinweis: Wenn Sie Python 3+ verwenden, sollten Sie stattdessen die Funktion print () verwenden
Angenommen, der Dateiname ist
foo.py
das folgende Snippetoder
Wie bei anderen Erweiterungen mit mehr Zeichen, zum Beispiel dem Dateinamen
foo.pypy
Wenn Sie aus einem absoluten Pfad extrahieren möchten
wird ausgegeben
foo
quelle
__file__
undsys.argv[0]
, siehe stackoverflow.com/questions/5851588/…Das erste Argument in sys ist der aktuelle Dateiname, damit dies funktioniert
quelle
Wenn Sie einen ungewöhnlichen Import durchführen (z. B. eine Optionsdatei), versuchen Sie Folgendes:
Beachten Sie, dass dadurch der absolute Pfad zur Datei zurückgegeben wird.
quelle
Wir können dies versuchen, um den aktuellen Skriptnamen ohne Erweiterung zu erhalten.
quelle
Da das OP nach dem Namen der aktuellen Skriptdatei gefragt hat, würde ich es vorziehen
quelle
Alle diese Antworten sind großartig, haben aber einige Probleme, die Sie möglicherweise nicht auf den ersten Blick sehen.
Lassen Sie uns definieren, was wir wollen - wir wollen den Namen des Skripts, das ausgeführt wurde, nicht den Namen des aktuellen Moduls - also
__file__
funktioniert es nur, wenn es im ausgeführten Skript verwendet wird, nicht in einem importierten Modul.sys.argv
ist auch fraglich - was wäre, wenn Ihr Programm von pytest aufgerufen würde? oder Pydoc Runner? oder wenn es von uwsgi aufgerufen wurde?und - es gibt eine dritte Methode, um den Skriptnamen zu erhalten, die ich in den Antworten nicht gesehen habe - Sie können den Stapel überprüfen.
Ein weiteres Problem ist, dass Sie (oder ein anderes Programm) mit
sys.argv
und manipulieren können__main__.__file__
- es könnte vorhanden sein, es könnte nicht sein. Es könnte gültig sein oder nicht. Zumindest können Sie überprüfen, ob das Skript (das gewünschte Ergebnis) vorhanden ist!Meine Bibliothek bitranox / lib_programname bei github macht genau das:
__main__
vorhanden__main__.__file__
vorhanden__main__.__file__
ein gültiges Ergebnis (existiert dieses Skript?)durch diese Art und Weise, meine Lösung funktioniert so weit mit
setup.py test
,uwsgi
,pytest
,pycharm pytest
,pycharm docrunner (doctest)
,dreampie
,eclipse
Es gibt auch einen schönen Blog-Artikel über dieses Problem von Dough Hellman, "Bestimmen des Namens eines Prozesses aus Python".
quelle
Meine schnelle schmutzige Lösung:
quelle
os.path
zumos.path.abspath(__file__)
gibt Ihnen einen absoluten Pfad (auchrelpath()
verfügbar).sys.argv[-1]
gibt Ihnen einen relativen Pfad.quelle
Ab Python 3.5 können Sie einfach Folgendes tun:
Weitere Informationen finden Sie hier: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Zum Beispiel habe ich eine Datei unter meinem Benutzerverzeichnis mit dem folgenden Namen
test.py
:Ausführen dieser Ausgänge:
quelle