Pridobivanje lokacije (poti) zagnane datoteke v Pythonu: __file__.

Posel

Če želite v Pythonu pridobiti lokacijo (pot) zagnane skriptne datoteke, uporabite __file__. To je uporabno za nalaganje drugih datotek na podlagi lokacije tekoče datoteke.

Do različice Python 3.8 je __file__ vrnil pot, ki je bila določena ob izvajanju ukaza python (ali python3 v nekaterih okoljih). Če je navedena relativna pot, se vrne relativna pot; če je navedena absolutna pot, se vrne absolutna pot.

V Pythonu 3.9 in novejših različicah se vrne absolutna pot ne glede na pot, ki je bila določena med izvajanjem.

Pojasnjene so naslednje vsebine.

  • os.getcwd(),__file__
  • Pridobi ime datoteke in ime imenika trenutno izvajane datoteke.
  • Pridobi absolutno pot do datoteke, ki se izvaja.
  • bere druge datoteke na podlagi lokacije trenutno izvajane datoteke.
  • Premakne trenutni imenik v imenik datoteke, ki se izvaja.
  • Enaka obdelava se lahko izvede ne glede na trenutni imenik v času izvajanja.

Za informacije o pridobivanju in spreminjanju trenutnega imenika (delovnega imenika) glejte naslednji članek.

Upoštevajte, da datoteke __file__ ni mogoče uporabiti v beležnici Jupyter (.ipynb).
Imenik, v katerem se nahaja .ipynb, se izvede kot trenutni imenik, ne glede na imenik, v katerem se zažene beležnica Jupyter.
V kodi je mogoče uporabiti os.chdir() za spremembo trenutnega imenika.

os.getcwd() in __file__.

V sistemu Windows lahko za preverjanje trenutnega imenika namesto ukaza pwd uporabite ukaz dir.

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

V nižji ravni (data\src) ustvarite skriptno datoteko Python (file_path.py) z naslednjo vsebino.

import os

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

Zaženite ukaz python (ali python3 v nekaterih okoljih) in navedite pot do skriptne datoteke.

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

Absolutno pot do trenutnega imenika lahko dobite z os.getcwd(). Uporabite lahko tudi __file__ za pridobitev poti, ki jo je določil ukaz python3.

Do različice Python 3.8 je __file__ vsebovala pot, ki je bila določena v ukazu python (ali python3). V zgornjem primeru se vrne relativna pot, ker je relativna, vrne pa se absolutna pot, če je absolutna.

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 in novejše vrnejo absolutno pot do datoteke __file__, ne glede na pot, določeno v ukazu python (ali python3).

V naslednjem primeru bomo kodo dodali v isto skriptno datoteko (file_path.py) v programu Python 3.7 in jo zagnali glede na zgornji imenik.

V Pythonu 3.7 se uporablja absolutna pot. Rezultati so prikazani na koncu tega poglavja.

Pridobi ime datoteke in ime imenika trenutno izvajane datoteke.

Če želite pridobiti ime datoteke in ime imenika zagnane datoteke, uporabite naslednjo funkcijo v modulu os.path standardne knjižnice.

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

Rezultat izvedbe.

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

Pridobi absolutno pot do datoteke, ki se izvaja.

Če je relativna pot pridobljena z __file__, jo lahko pretvorite v absolutno pot z os.path.abspath(). Tudi imenike lahko dobimo kot absolutne poti.

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

Rezultat izvedbe.

# 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

Če je v ukazu os.path.abspath() določena absolutna pot, se vrne takšna, kot je. Če je torej __file__ absolutna pot, naslednje ne bo povzročilo napake.

  • os.path.abspath(__file__)

bere druge datoteke na podlagi lokacije trenutno izvajane datoteke.

Če želite prebrati druge datoteke na podlagi lokacije (poti) datoteke, ki se izvaja, združite naslednji dve datoteki z uporabo os.path.join().

  • Imenik datoteke, ki se izvaja
  • Relativna pot do datoteke, ki jo je treba prebrati iz tekoče datoteke.

Če želite prebrati datoteko v istem imeniku kot datoteko, ki jo zaganjate, združite imena datotek.

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

Rezultat izvedbe.

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

Zgornja raven je označena z “. \”. Lahko jo pustite tako, kot je, lahko pa uporabite os.path.normpath() za normalizacijo poti in odstranitev dodatnih “. \” in druge znake.

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

Rezultat izvedbe.

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

Premakne trenutni imenik v imenik datoteke, ki se izvaja.

Uporabite os.chdir() za premik trenutnega imenika v imenik datoteke, ki se izvaja v skripti.

Vidite, da ga premakne os.getcwd().

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

Rezultat izvedbe.

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

Ko je trenutni imenik premaknjen, ga pri branju datoteke ni več treba združiti z imenikom tekoče datoteke. Navedete lahko samo pot glede na imenik tekoče datoteke.

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

Rezultat izvedbe.

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

Enaka obdelava se lahko izvede ne glede na trenutni imenik v času izvajanja.

Kot smo pokazali, je mogoče datoteke nalagati na podlagi lokacije datoteke skripte, neodvisno od trenutnega imenika med izvajanjem, z uporabo ene od naslednjih metod.

  • Združite imenik tekoče datoteke in relativno pot do datoteke, ki jo je treba prebrati iz tekoče datoteke, z uporabo os.path.join().
  • Premakne trenutni imenik v imenik datoteke, ki se izvaja.

Lažje je premakniti trenutni imenik, seveda pa je treba upoštevati, da je bil trenutni imenik premaknjen, če želite nato prebrati ali zapisati več datotek.

Rezultati prejšnjih primerov so povzeti v nadaljevanju.

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

Rezultat določitve absolutne poti je naslednji.

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

Rezultat premikanja trenutnega imenika v terminalu in izvajanja iste skriptne datoteke je prikazan spodaj. Vidite lahko, da je mogoče isto datoteko prebrati, tudi če se izvede z drugega mesta.

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