662 Stimmen

Name des aktuellen Skripts in Python abfragen

Ich versuche, den Namen des Python-Skripts abzurufen, das gerade ausgeführt wird.

Ich habe ein Skript namens foo.py und ich würde gerne so etwas tun, um den Skriptnamen zu erhalten:

print(Scriptname)

957voto

Sven Marnach Punkte 525472

Sie können verwenden __file__ um den Namen der aktuellen Datei zu erhalten. Bei Verwendung im Hauptmodul ist dies der Name des Skripts, das ursprünglich aufgerufen wurde.

Wenn Sie den Verzeichnisteil weglassen wollen (der möglicherweise vorhanden ist), können Sie os.path.basename(__file__) .

240voto

Chris Morgan Punkte 78929
import sys
print(sys.argv[0])

Damit wird gedruckt foo.py für python foo.py , dir/foo.py für python dir/foo.py , usw. Es ist das erste Argument für python . (Beachten Sie, dass es nach py2exe so aussehen würde foo.exe .)

161voto

Yoel Punkte 8439

Der Vollständigkeit halber dachte ich, dass es sich lohnt, die verschiedenen möglichen Ergebnisse zusammenzufassen und Verweise auf das genaue Verhalten jedes einzelnen Ergebnisses zu geben.

Die Antwort setzt sich aus vier Abschnitten zusammen:

  1. Eine Liste mit verschiedenen Ansätzen, die den vollständigen Pfad zum aktuell ausgeführten Skript zurückgeben.

  2. Eine Warnung zum Umgang mit relativen Pfaden.

  3. Eine Empfehlung zum Umgang mit symbolischen Links.

  4. Ein Bericht über einige Methoden, die verwendet werden können, um den tatsächlichen Dateinamen mit oder ohne Suffix aus dem vollständigen Dateipfad zu extrahieren.


Extrahieren des vollständigen Dateipfads

  • __file__ ist die aktuell ausgeführte Datei, wie in der offizielle Dokumentation :

    __file__ ist der Pfadname der Datei, aus der das Modul geladen wurde, wenn es aus einer Datei geladen wurde. Der __file__ Attribut kann bei bestimmten Modultypen fehlen, wie z. B. C Module, die statisch in den Interpreter gelinkt sind; für Erweiterungsmodule, die dynamisch aus einer Shared Library geladen werden, ist es der Pfadname der Shared-Library-Datei.

    Desde Python3.4 ab, pro Ausgabe 18416 , __file__ ist immer ein absoluter Pfad, es sei denn, die aktuell ausgeführte Datei ist ein Skript, das direkt ausgeführt wurde (nicht über den Interpreter mit der Option -m Befehlszeilenoption) unter Verwendung eines relativen Pfades.

  • __main__.__file__ (erfordert den Import von __main__ ) greift einfach auf die oben erwähnte __file__ Attribut des Hauptmodul z.B. des Skripts, das von der Kommandozeile aus aufgerufen wurde.

    Desde Python3.9 ab, pro Ausgabe 20443 El __file__ Attribut des __main__ Modul wurde ein absoluter Pfad statt eines relativen Pfades.

  • sys.argv[0] (erfordert den Import von sys ) ist der Name des Skripts, das von der Befehlszeile aus aufgerufen wurde, und kann ein absoluter Pfad sein, wie im Abschnitt offizielle Dokumentation :

    argv[0] ist der Skriptname (es ist betriebssystemabhängig, ob dies ein vollständiger Pfadname ist oder nicht). Wurde der Befehl mit der Option -c Befehlszeilenoption für den Interpreter, argv[0] wird auf die Zeichenkette '-c' . Wenn kein Skriptname an den Python-Interpreter übergeben wurde, argv[0] ist die leere Zeichenkette.

    Wie bereits in eine andere Antwort auf diese Frage , Python Skripte, die in eigenständige ausführbare Programme mit Hilfe von Tools wie py2exe o PyInstaller bei diesem Ansatz möglicherweise nicht das gewünschte Ergebnis (d. h. sys.argv[0] würde den Namen der ausführbaren Datei enthalten und nicht den Namen des Hauptprogramms Python Datei innerhalb dieser ausführbaren Datei).

  • Wenn keine der oben genannten Optionen zu funktionieren scheint, was wahrscheinlich auf einen atypischen Ausführungsprozess oder einen unregelmäßigen Importvorgang zurückzuführen ist, kann die prüfen Modul könnte sich als nützlich erweisen, wie in eine andere Antwort auf diese Frage :

    import inspect
    source_file_path = inspect.getfile(inspect.currentframe())

    Allerdings, inspect.currentframe() würde eine Ausnahme auslösen, wenn sie in einer Implementierung ohne Python Stapelrahmen.

    Beachten Sie, dass inspect.getfile(...) ist vorzuziehen gegenüber inspect.getsourcefile(...) weil letztere löst eine TypeError-Ausnahme aus wenn es nur eine Binärdatei, nicht aber die zugehörige Quelldatei ermitteln kann (siehe auch diese Antwort auf eine andere Frage ).

  • Desde Python3.6 aufwärts, und wie ausführlich in eine andere Antwort auf diese Frage ist es möglich, eine externe Open-Source-Bibliothek zu installieren, lib_programmname die auf eine vollständige Lösung dieses Problems zugeschnitten ist.

    Diese Bibliothek durchläuft alle oben aufgeführten Ansätze, bis ein gültiger Pfad zurückgegeben wird. Wenn alle Ansätze fehlschlagen, wird eine Ausnahme ausgelöst. Sie versucht auch, verschiedene Fallstricke zu umgehen, wie z.B. Aufrufe über die pytest Rahmen oder der pydoc Modul.

    import lib_programname
    # this returns the fully resolved path to the launched python program
    path_to_program = lib_programname.get_path_executed_script()  # type: pathlib.Path

Handhabung relativer Pfade

Wenn es sich um einen Ansatz handelt, der einen relativen Pfad zurückgibt, könnte es verlockend sein, verschiedene Funktionen zur Pfadmanipulation aufzurufen, wie z. B. os.path.abspath(...) o os.path.realpath(...) um den vollständigen oder echten Pfad zu extrahieren.

Diese Methoden sind jedoch auf den aktuellen Pfad angewiesen, um den vollständigen Pfad abzuleiten. Wenn also ein Programm zunächst das aktuelle Arbeitsverzeichnis ändert, zum Beispiel über os.chdir(...) und erst dann diese Methoden aufruft, würden sie einen falschen Pfad zurückgeben.


Umgang mit symbolischen Links

Wenn es sich bei dem aktuellen Skript um einen symbolischen Link handelt, würden alle oben genannten Punkte den Pfad des symbolischen Links zurückgeben und nicht den Pfad der echten Datei und os.path.realpath(...) aufgerufen werden, um letztere zu extrahieren.


Weitere Manipulationen, die den eigentlichen Dateinamen extrahieren

os.path.basename(...) kann für jede der oben genannten Dateien aufgerufen werden, um den tatsächlichen Dateinamen und os.path.splitext(...) kann auf den eigentlichen Dateinamen angewandt werden, um dessen Suffix abzuschneiden, wie in os.path.splitext(os.path.basename(...)) .

Desde Python 3.4 ab, pro PEP 428 El PurePath Klasse der pathlib Modul kann auch für die oben genannten Produkte verwendet werden. Speziell, pathlib.PurePath(...).name extrahiert den tatsächlichen Dateinamen und pathlib.PurePath(...).stem extrahiert den eigentlichen Dateinamen ohne dessen Suffix.

69voto

Ambroz Bizjak Punkte 7569

Beachten Sie, dass __file__ gibt die Datei an, in der sich dieser Code befindet, der importiert werden kann und sich von der zu interpretierenden Hauptdatei unterscheidet. Um die Hauptdatei zu erhalten, muss das spezielle __main__ Modul verwendet werden kann:

import __main__ as main
print(main.__file__)

Beachten Sie, dass __main__.__file__ funktioniert in Python 2.7, aber nicht in 3.2, also verwenden Sie die import-as-Syntax wie oben, um es portabel zu machen.

58voto

Manoj Sahu Punkte 2576

Die oben genannten Antworten sind gut. Aber ich fand diese Methode mit den obigen Ergebnissen effizienter.
Dies führt zu einem tatsächlichen Skriptdateinamen und nicht zu einem Pfad.

import sys    
import os    
file_name =  os.path.basename(sys.argv[0])

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X