Získanie umiestnenia (cesty) spusteného súboru v jazyku Python: __file__.

obchodné

Ak chcete získať umiestnenie (cestu) spusteného súboru skriptu v jazyku Python, použite príkaz __file__. Je to užitočné na načítanie iných súborov na základe umiestnenia spusteného súboru.

Do verzie Python 3.8 __file__ vracia cestu zadanú pri vykonávaní príkazu python (alebo príkazu python3 v niektorých prostrediach). Ak je zadaná relatívna cesta, vráti sa relatívna cesta; ak je zadaná absolútna cesta, vráti sa absolútna cesta.

V jazyku Python 3.9 a novších verziách sa vracia absolútna cesta bez ohľadu na cestu zadanú počas behu.

Vysvetľuje sa nasledujúci obsah.

  • os.getcwd(),__file__
  • Získanie názvu súboru a názvu adresára aktuálne vykonávaného súboru.
  • Získanie absolútnej cesty k spúšťanému súboru.
  • Číta ďalšie súbory na základe umiestnenia aktuálne vykonávaného súboru.
  • Presun aktuálneho adresára do adresára vykonávaného súboru.
  • Rovnaké spracovanie sa môže vykonať bez ohľadu na aktuálny adresár počas behu.

Informácie o získaní a zmene aktuálneho adresára (pracovného adresára) nájdete v nasledujúcom článku.

Všimnite si, že __file__ nemožno použiť v Jupyter Notebook (.ipynb).
Adresár, v ktorom sa nachádza súbor .ipynb, sa spustí ako aktuálny adresár bez ohľadu na adresár, v ktorom je spustený Jupyter Notebook.
Na zmenu aktuálneho adresára je možné v kóde použiť funkciu os.chdir().

os.getcwd() a __file__.

V systéme Windows môžete namiesto príkazu pwd použiť príkaz dir na kontrolu aktuálneho adresára.

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

Vytvorte súbor skriptu Python (file_path.py) s nasledujúcim obsahom na nižšej úrovni (data\src).

import os

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

Spustite príkaz python (alebo v niektorých prostrediach príkaz python3) a zadajte cestu k súboru so skriptom.

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

Absolútnu cestu k aktuálnemu adresáru možno získať pomocou funkcie os.getcwd(). Na získanie cesty zadanej príkazom python3 môžete použiť aj príkaz __file__.

Do verzie Python 3.8 bude __file__ obsahovať cestu zadanú v príkaze python (alebo python3). Vo vyššie uvedenom príklade sa vráti relatívna cesta, pretože je relatívna, ale absolútna cesta sa vráti, ak je absolútna.

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 a novší vráti absolútnu cestu k súboru __file__ bez ohľadu na cestu zadanú v príkaze python (alebo python3).

V nasledujúcom príklade pridáme kód do rovnakého súboru skriptu (file_path.py) v jazyku Python 3.7 a spustíme ho vzhľadom na vyššie uvedený adresár.

V jazyku Python 3.7 sa používa absolútna cesta. Výsledky sú uvedené na konci tejto časti.

Získanie názvu súboru a názvu adresára aktuálne vykonávaného súboru.

Ak chcete získať názov súboru a názov adresára spusteného súboru, použite nasledujúcu funkciu v module os.path štandardnej knižnice.

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

Výsledok vykonania.

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

Získanie absolútnej cesty k spúšťanému súboru.

Ak je relatívna cesta získaná pomocou __file__, možno ju previesť na absolútnu cestu pomocou os.path.abspath(). Adresáre možno získať aj ako absolútne cesty.

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

Výsledok vykonania.

# 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

Ak je v príkaze os.path.abspath() zadaná absolútna cesta, vráti sa taká, aká je. Ak je teda __file__ absolútna cesta, nasledujúce príkazy nespôsobia chybu.

  • os.path.abspath(__file__)

Číta ďalšie súbory na základe umiestnenia aktuálne vykonávaného súboru.

Ak chcete čítať ďalšie súbory na základe umiestnenia (cesty) spúšťaného súboru, spojte nasledujúce dva súbory pomocou os.path.join().

  • Adresár vykonávaného súboru
  • Relatívna cesta k súboru, ktorý sa má načítať zo spusteného súboru.

Ak chcete čítať súbor v tom istom adresári ako súbor, ktorý spúšťate, stačí spojiť názov súboru.

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

Výsledok vykonania.

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

Horná úroveň je reprezentovaná symbolom „. \“. Môžete ju nechať tak, ako je, ale môžete použiť os.path.normpath() na normalizáciu cesty a odstránenie dodatočného „. \“ a ďalšie znaky.

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

Výsledok vykonania.

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

Presun aktuálneho adresára do adresára vykonávaného súboru.

Pomocou funkcie os.chdir() presuniete aktuálny adresár do adresára súboru, ktorý sa vykonáva v skripte.

Vidíte, že je presunutá pomocou funkcie os.getcwd().

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

Výsledok vykonania.

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

Keď sa aktuálny adresár presunie, nie je potrebné ho pri čítaní súboru spájať s adresárom spusteného súboru. Stačí zadať cestu relatívnu k adresáru bežiaceho súboru.

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

Výsledok vykonania.

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

Rovnaké spracovanie sa môže vykonať bez ohľadu na aktuálny adresár počas behu.

Ako sme ukázali, je možné načítať súbory na základe umiestnenia súboru skriptu, nezávisle od aktuálneho adresára v čase behu, pomocou jednej z nasledujúcich metód.

  • Spojte adresár spusteného súboru a relatívnu cestu k súboru, ktorý sa má načítať zo spusteného súboru, pomocou os.path.join().
  • Presun aktuálneho adresára do adresára vykonávaného súboru.

Je jednoduchšie presunúť aktuálny adresár, ale samozrejme, ak chcete potom čítať alebo zapisovať ďalšie súbory, musíte vziať do úvahy, že aktuálny adresár bol presunutý.

Výsledky predchádzajúcich príkladov sú zhrnuté nižšie.

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

Výsledok zadania absolútnej cesty je nasledovný.

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

Výsledok presunu aktuálneho adresára v termináli a spustenia toho istého súboru skriptu je zobrazený nižšie. Vidíte, že ten istý súbor sa dá prečítať, aj keď sa spustí z iného miesta.

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