Ermitteln der Position (Pfad) einer laufenden Datei in Python: __file__.

Geschäft

Um den Ort (Pfad) einer laufenden Skriptdatei in Python zu ermitteln, verwenden Sie __file__. Dies ist nützlich, um andere Dateien auf der Grundlage des Speicherorts der laufenden Datei zu laden.

Bis Python 3.8 gibt __file__ den Pfad zurück, der bei der Ausführung des python-Befehls (oder python3-Befehls in einigen Umgebungen) angegeben wurde. Wenn ein relativer Pfad angegeben wird, wird der relative Pfad zurückgegeben; wenn ein absoluter Pfad angegeben wird, wird der absolute Pfad zurückgegeben.

In Python 3.9 und höher wird der absolute Pfad zurückgegeben, unabhängig von dem zur Laufzeit angegebenen Pfad.

Die folgenden Inhalte werden erläutert.

  • os.getcwd(),__file__
  • Ermittelt den Dateinamen und den Verzeichnisnamen der aktuell ausgeführten Datei.
  • Ermittelt den absoluten Pfad der auszuführenden Datei.
  • Liest andere Dateien basierend auf dem Speicherort der aktuell ausgeführten Datei.
  • Verschiebt das aktuelle Verzeichnis in das Verzeichnis der auszuführenden Datei.
  • Unabhängig vom aktuellen Verzeichnis kann zur Laufzeit die gleiche Verarbeitung durchgeführt werden.

Im folgenden Artikel finden Sie Informationen zum Abrufen und Ändern des aktuellen Verzeichnisses (Arbeitsverzeichnis).

Beachten Sie, dass __file__ nicht in Jupyter Notebook (.ipynb) verwendet werden kann.
Das Verzeichnis, in dem sich .ipynb befindet, wird als aktuelles Verzeichnis ausgeführt, unabhängig davon, in welchem Verzeichnis Jupyter Notebook gestartet wird.
Es ist möglich, os.chdir() im Code zu verwenden, um das aktuelle Verzeichnis zu ändern.

os.getcwd() und __file__.

Unter Windows können Sie anstelle von pwd den Befehl dir verwenden, um das aktuelle Verzeichnis zu überprüfen.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

Erstellen Sie eine Python-Skriptdatei (file_path.py) mit folgendem Inhalt auf der unteren Ebene (data\src).

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

Führen Sie den Python-Befehl (oder in manchen Umgebungen den Python3-Befehl) aus und geben Sie den Pfad zur Skriptdatei an.

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

Der absolute Pfad zum aktuellen Verzeichnis kann mit os.getcwd() ermittelt werden. Sie können auch __file__ verwenden, um den vom Python3-Befehl angegebenen Pfad zu erhalten.

Bis Python 3.8 enthält __file__ den Pfad, der im Befehl python (oder python3) angegeben ist. Im obigen Beispiel wird der relative Pfad zurückgegeben, weil er relativ ist, aber der absolute Pfad wird zurückgegeben, wenn er absolut ist.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py

Python 3.9 und höher gibt den absoluten Pfad zu __file__ zurück, unabhängig vom Pfad, der im python (oder python3) Befehl angegeben wurde.

Im folgenden Beispiel fügen wir den Code zur gleichen Skriptdatei (file_path.py) in Python 3.7 hinzu und führen ihn relativ zum obigen Verzeichnis aus.

In Python 3.7 wird der absolute Pfad verwendet. Die Ergebnisse sind am Ende dieses Abschnitts aufgeführt.

Ermittelt den Dateinamen und den Verzeichnisnamen der aktuell ausgeführten Datei.

Um den Dateinamen und den Verzeichnisnamen der laufenden Datei zu erhalten, verwenden Sie die folgende Funktion im Modul os.path der Standardbibliothek.

  • os.path.basename()
  • os.path.dirname()
print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

Ergebnis der Ausführung.

# basename:     file_path.py
# dirname:      data/src

Ermittelt den absoluten Pfad der auszuführenden Datei.

Wenn ein relativer Pfad mit __file__ ermittelt wird, kann er mit os.path.abspath() in einen absoluten Pfad umgewandelt werden. Verzeichnisse können auch als absolute Pfade ermittelt werden.

print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

Ergebnis der Ausführung.

# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Wenn ein absoluter Pfad in os.path.abspath() angegeben wird, wird er so zurückgegeben, wie er ist. Wenn also __file__ ein absoluter Pfad ist, wird das Folgende keinen Fehler verursachen.

  • os.path.abspath(__file__)

Liest andere Dateien basierend auf dem Speicherort der aktuell ausgeführten Datei.

Wenn Sie andere Dateien auf der Grundlage des Speicherorts (Pfads) der ausgeführten Datei lesen möchten, fügen Sie die folgenden zwei Dateien mit os.path.join() zusammen.

  • Verzeichnis der auszuführenden Datei
  • Relativer Pfad zu der Datei, die aus der laufenden Datei gelesen werden soll.

Wenn Sie eine Datei lesen wollen, die sich im selben Verzeichnis befindet wie die Datei, die Sie gerade ausführen, müssen Sie nur den Dateinamen aneinanderhängen.

print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

Ergebnis der Ausführung.

# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!

Die obere Ebene wird durch “. \”. Sie können es so lassen, wie es ist, aber Sie können os.path.normpath() verwenden, um den Pfad zu normalisieren und zusätzliche “. \” und andere Zeichen entfernen.

print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')

print('target_path_2: ', target_path_2)
print('normalize    : ', os.path.normpath(target_path_2))

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Ergebnis der Ausführung.

# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Verschiebt das aktuelle Verzeichnis in das Verzeichnis der auszuführenden Datei.

Verwenden Sie os.chdir(), um das aktuelle Verzeichnis in das Verzeichnis der Datei zu verschieben, die im Skript ausgeführt wird.

Sie können sehen, dass es durch os.getcwd() verschoben wird.

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

Ergebnis der Ausführung.

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Sobald das aktuelle Verzeichnis verschoben wurde, muss es beim Lesen der Datei nicht mehr mit dem Verzeichnis der laufenden Datei verkettet werden. Sie können einfach den Pfad relativ zum Verzeichnis der laufenden Datei angeben.

print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Ergebnis der Ausführung.

# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Unabhängig vom aktuellen Verzeichnis kann zur Laufzeit die gleiche Verarbeitung durchgeführt werden.

Wie wir gezeigt haben, ist es möglich, Dateien auf der Grundlage des Speicherorts der Skriptdatei zu laden, unabhängig vom aktuellen Verzeichnis zur Laufzeit, indem eine der folgenden Methoden verwendet wird.

  • Verketten Sie das Verzeichnis der laufenden Datei und den relativen Pfad zu der Datei, die aus der laufenden Datei gelesen werden soll, mit os.path.join().
  • Verschiebt das aktuelle Verzeichnis in das Verzeichnis der auszuführenden Datei.

Es ist einfacher, das aktuelle Verzeichnis zu verschieben, aber wenn Sie danach weitere Dateien lesen oder schreiben wollen, müssen Sie natürlich berücksichtigen, dass das aktuelle Verzeichnis verschoben wurde.

Die Ergebnisse der vorangegangenen Beispiele sind im Folgenden zusammengefasst.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py
# basename:     file_path.py
# dirname:      data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Das Ergebnis der Angabe des absoluten Pfades ist wie folgt.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename:     file_path.py
# dirname:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize    :  /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Das Ergebnis des Wechselns des aktuellen Verzeichnisses im Terminal und des Ausführens derselben Skriptdatei ist unten dargestellt. Sie sehen, dass dieselbe Datei gelesen werden kann, auch wenn sie an einem anderen Ort ausgeführt wird.

cd data/src

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

python3 file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__:     file_path.py
# basename:     file_path.py
# dirname:      
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  ../dst/target_2.txt
# normalize    :  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!