Obținerea locației (calea) unui fișier în execuție în Python: __file__.

Afaceri

Pentru a obține locația (calea) unui fișier de script în execuție în Python, utilizați __file__. Acest lucru este util pentru a încărca alte fișiere pe baza locației fișierului în curs de execuție.

Până la Python 3.8, __file__ returnează calea specificată la executarea comenzii python (sau a comenzii python3 în anumite medii). Dacă este specificată o cale relativă, este returnată calea relativă; dacă este specificată o cale absolută, este returnată calea absolută.

În Python 3.9 și versiunile ulterioare, calea absolută este returnată indiferent de calea specificată la momentul execuției.

Sunt explicate următoarele conținuturi.

  • os.getcwd(),__file__
  • Obține numele de fișier și numele de director al fișierului în curs de execuție.
  • Obține calea absolută a fișierului care se execută.
  • Citește alte fișiere pe baza locației fișierului în curs de execuție.
  • Mută directorul curent în directorul fișierului care se execută.
  • Aceeași procesare poate fi efectuată indiferent de directorul curent la momentul execuției.

Consultați următorul articol pentru informații despre obținerea și modificarea directorului curent (director de lucru).

Rețineți că __file__ nu poate fi utilizat în Jupyter Notebook (.ipynb).
Directorul în care se află .ipynb va fi executat ca director curent, indiferent de directorul în care este inițiat Jupyter Notebook.
Este posibil să se utilizeze os.chdir() în cod pentru a schimba directorul curent.

os.getcwd() și __file__.

În Windows, puteți utiliza comanda dir în loc de pwd pentru a verifica directorul curent.

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

Creați un fișier script Python (file_path.py) cu următorul conținut la nivelul inferior (data\src).

import os

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

Rulați comanda python (sau comanda python3 în anumite medii) specificând calea către fișierul script.

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

Calea absolută către directorul curent poate fi obținută cu os.getcwd(). De asemenea, puteți utiliza __file__ pentru a obține calea specificată de comanda python3.

Până la Python 3.8, __file__ va conține calea specificată în comanda python (sau python3). În exemplul de mai sus, calea relativă este returnată pentru că este relativă, dar calea absolută este returnată dacă este absolută.

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 versiunile ulterioare returnează calea absolută către __file__, indiferent de calea specificată în comanda python (sau python3).

În exemplul următor, vom adăuga codul la același fișier script (file_path.py) în Python 3.7 și îl vom rula în raport cu directorul de mai sus.

În Python 3.7, se utilizează calea absolută. Rezultatele sunt prezentate la sfârșitul acestei secțiuni.

Obține numele de fișier și numele de director al fișierului în curs de execuție.

Pentru a obține numele de fișier și numele de director al fișierului care rulează, utilizați următoarea funcție din modulul os.path al bibliotecii standard.

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

Rezultatul execuției.

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

Obține calea absolută a fișierului care se execută.

În cazul în care se obține o cale relativă cu __file__, aceasta poate fi convertită într-o cale absolută cu os.path.abspath(). De asemenea, directoarele pot fi obținute ca căi absolute.

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

Rezultatul execuției.

# 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

Dacă în os.path.abspath() este specificată o cale absolută, aceasta va fi returnată ca atare. Prin urmare, dacă __file__ este o cale absolută, următoarele nu vor cauza o eroare.

  • os.path.abspath(__file__)

Citește alte fișiere pe baza locației fișierului în curs de execuție.

Dacă doriți să citiți alte fișiere în funcție de locația (calea) fișierului care se execută, uniți următoarele două fișiere folosind os.path.join().

  • Directorul fișierului care se execută
  • Calea relativă a fișierului care urmează să fie citit din fișierul în execuție.

Dacă doriți să citiți un fișier din același director cu fișierul pe care îl executați, trebuie doar să concatenați numele fișierului.

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

Rezultatul execuției.

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

Nivelul superior este reprezentat de „. \”. Îl puteți lăsa așa cum este, dar puteți folosi os.path.normpath() pentru a normaliza calea și a elimina extrasul „. \” și alte caractere.

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

Rezultatul execuției.

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

Mută directorul curent în directorul fișierului care se execută.

Utilizați os.chdir() pentru a muta directorul curent în directorul fișierului care este executat în script.

Puteți vedea că acesta este mutat de os.getcwd().

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

Rezultatul execuției.

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

Odată ce directorul curent a fost mutat, nu mai este necesar să se concateneze cu directorul fișierului în curs de execuție la citirea acestuia. Puteți specifica pur și simplu calea relativă la directorul fișierului în curs de execuție.

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

Rezultatul execuției.

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

Aceeași procesare poate fi efectuată indiferent de directorul curent la momentul execuției.

După cum am arătat, este posibilă încărcarea fișierelor pe baza locației fișierului de script, independent de directorul curent în momentul execuției, utilizând una dintre următoarele metode.

  • Concatenați directorul fișierului în execuție și calea relativă către fișierul care urmează să fie citit din fișierul în execuție utilizând os.path.join().
  • Mută directorul curent în directorul fișierului care se execută.

Este mai ușor să mutați directorul curent, dar, desigur, dacă doriți să citiți sau să scrieți mai multe fișiere după aceea, trebuie să țineți cont de faptul că directorul curent a fost mutat.

Rezultatele exemplelor anterioare sunt rezumate mai jos.

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

Rezultatul specificării căii absolute este următorul.

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

Rezultatul mutării directorului curent în terminal și al executării aceluiași fișier script este prezentat mai jos. Puteți vedea că același fișier poate fi citit chiar dacă este executat dintr-o locație diferită.

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