Uzyskanie lokalizacji (ścieżki) uruchomionego pliku w Pythonie: __file__.

Biznes

Aby uzyskać lokalizację (ścieżkę) działającego pliku skryptu w Pythonie, użyj __file__. Jest to przydatne do ładowania innych plików w oparciu o lokalizację uruchomionego pliku.

Aż do Pythona 3.8, __file__ zwraca ścieżkę określoną podczas wykonywania polecenia python (lub polecenia python3 w niektórych środowiskach). Jeśli podano ścieżkę względną, zwracana jest ścieżka względna; jeśli podano ścieżkę bezwzględną, zwracana jest ścieżka bezwzględna.

W Pythonie 3.9 i nowszych, bezwzględna ścieżka jest zwracana niezależnie od ścieżki określonej w czasie wykonywania.

Objaśnione są następujące treści.

  • os.getcwd(),__file__
  • Uzyskaj nazwę pliku i nazwę katalogu aktualnie wykonywanego pliku.
  • Uzyskaj bezwzględną ścieżkę do pliku, który ma zostać wykonany.
  • Odczytuje inne pliki w oparciu o lokalizację aktualnie wykonywanego pliku.
  • Przenosi bieżący katalog do katalogu wykonywanego pliku.
  • To samo przetwarzanie może być wykonane niezależnie od bieżącego katalogu w czasie uruchamiania.

Zobacz poniższy artykuł, aby uzyskać informacje na temat uzyskiwania i zmiany bieżącego katalogu (katalogu roboczego).

Zauważ, że __file__ nie może być użyty w Jupyter Notebook (.ipynb).
Katalog, w którym znajduje się .ipynb będzie wykonywany jako katalog bieżący, niezależnie od katalogu, w którym uruchomiony jest Jupyter Notebook.
Możliwe jest użycie os.chdir() w kodzie, aby zmienić bieżący katalog.

os.getcwd() i __file__.

W Windows, możesz użyć polecenia dir zamiast pwd, aby sprawdzić bieżący katalog.

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

Utwórz plik skryptu Pythona (file_path.py) z następującą zawartością w niższym poziomie (data_src).

import os

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

Uruchom polecenie python (lub w niektórych środowiskach polecenie python3) podając ścieżkę do pliku skryptu.

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

Absolutna ścieżka do bieżącego katalogu może być uzyskana za pomocą os.getcwd(). Możesz również użyć __file__, aby uzyskać ścieżkę określoną przez polecenie python3.

Do Pythona 3.8, __file__ będzie zawierał ścieżkę podaną w poleceniu python (lub python3). W powyższym przykładzie, względna ścieżka jest zwracana, ponieważ jest względna, ale bezwzględna ścieżka jest zwracana, jeśli jest bezwzględna.

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 i nowszy zwraca bezwzględną ścieżkę do pliku __file__, niezależnie od ścieżki podanej w poleceniu python (lub python3).

W poniższym przykładzie dodamy kod do tego samego pliku skryptu (file_path.py) w Pythonie 3.7 i uruchomimy go względem powyższego katalogu.

W Pythonie 3.7 używana jest ścieżka bezwzględna. Wyniki pokazane są na końcu tej sekcji.

Uzyskaj nazwę pliku i nazwę katalogu aktualnie wykonywanego pliku.

Aby uzyskać nazwę pliku i nazwę katalogu uruchomionego pliku, użyj następującej funkcji w module os.path biblioteki standardowej.

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

Wynik egzekucji.

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

Uzyskaj bezwzględną ścieżkę do pliku, który ma zostać wykonany.

Jeśli względna ścieżka jest uzyskana za pomocą __file__, może być przekonwertowana na ścieżkę absolutną za pomocą os.path.abspath(). Katalogi mogą być również uzyskiwane jako ścieżki bezwzględne.

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

Wynik egzekucji.

# 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

Jeśli w os.path.abspath() podana jest ścieżka absolutna, zostanie ona zwrócona w takiej postaci. Dlatego, jeśli __file__ jest ścieżką absolutną, poniższe nie spowoduje błędu.

  • os.path.abspath(__file__)

Odczytuje inne pliki w oparciu o lokalizację aktualnie wykonywanego pliku.

Jeśli chcesz odczytać inne pliki w oparciu o lokalizację (ścieżkę) wykonywanego pliku, połącz dwa poniższe pliki za pomocą os.path.join().

  • Katalog wykonywanego pliku
  • Względna ścieżka do pliku, który ma być odczytany z działającego pliku.

Jeśli chcesz odczytać plik znajdujący się w tym samym katalogu, co plik, który uruchamiasz, po prostu połącz nazwy plików.

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())

Wynik egzekucji.

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

Górny poziom jest reprezentowany przez „. \”. Możesz zostawić to tak jak jest, ale możesz użyć os.path.normpath() aby znormalizować ścieżkę i usunąć dodatkowe „. \” i innych znaków.

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())

Wynik egzekucji.

# [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" !!

Przenosi bieżący katalog do katalogu wykonywanego pliku.

Użyj os.chdir() aby przenieść bieżący katalog do katalogu pliku wykonywanego w skrypcie.

Możesz zobaczyć, że jest on przenoszony przez os.getcwd().

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

Wynik egzekucji.

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

Po przeniesieniu bieżącego katalogu, nie ma potrzeby konkatenacji go z katalogiem działającego pliku podczas odczytu pliku. Możesz po prostu podać ścieżkę względną do katalogu działającego pliku.

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())

Wynik egzekucji.

# [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" !!

To samo przetwarzanie może być wykonane niezależnie od bieżącego katalogu w czasie uruchamiania.

Jak pokazaliśmy, możliwe jest wczytywanie plików na podstawie lokalizacji pliku skryptu, niezależnie od bieżącego katalogu w czasie wykonywania, za pomocą jednej z poniższych metod.

  • Złącz katalog działającego pliku i względną ścieżkę do pliku, który ma zostać odczytany z działającego pliku używając os.path.join().
  • Przenosi bieżący katalog do katalogu wykonywanego pliku.

Łatwiej jest przenieść bieżący katalog, ale oczywiście, jeśli chcesz czytać lub pisać więcej plików po tym, musisz wziąć pod uwagę, że bieżący katalog został przeniesiony.

Wyniki poprzednich przykładów są podsumowane poniżej.

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" !!

Wynik podania ścieżki bezwzględnej jest następujący.

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" !!

Wynik przeniesienia bieżącego katalogu w terminalu i wykonania tego samego pliku skryptu jest pokazany poniżej. Widać, że ten sam plik może być odczytany nawet jeśli jest wykonywany z innej lokalizacji.

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" !!

Copied title and URL