Egy futó fájl helyének (elérési útvonalának) megkeresése Pythonban: __file__.

Üzleti

A Pythonban egy futó szkriptfájl helyének (elérési útvonalának) megadásához használja a __file__ parancsot. Ez hasznos más fájlok betöltéséhez a futó fájl helye alapján.

A Python 3.8-ig a __file__ a python parancs (vagy egyes környezetekben a python3 parancs) végrehajtásakor megadott elérési utat adja vissza. Ha relatív elérési útvonal van megadva, akkor a relatív elérési útvonal kerül visszaadásra; ha abszolút elérési útvonal van megadva, akkor az abszolút elérési útvonal kerül visszaadásra.

A Python 3.9 és újabb verziókban az abszolút elérési útvonal a futáskor megadott elérési úttól függetlenül visszakerül.

A következő tartalmakat ismertetjük.

  • os.getcwd(),__file__
  • Az aktuálisan végrehajtott fájl fájlnevének és könyvtárnevének lekérdezése.
  • A végrehajtandó fájl abszolút elérési útjának lekérdezése.
  • Más fájlok beolvasása az aktuálisan futó fájl helye alapján.
  • Az aktuális könyvtár áthelyezése a végrehajtandó fájl könyvtárába.
  • Ugyanaz a feldolgozás végezhető el az aktuális könyvtártól függetlenül futásidőben.

Az aktuális könyvtár (munkakönyvtár) lekérdezésével és megváltoztatásával kapcsolatos információkat lásd a következő cikkben.

Vegye figyelembe, hogy a __file__ nem használható Jupyter Notebook (.ipynb) esetén.
Az a könyvtár, ahol az .ipynb található, lesz az aktuális könyvtár, függetlenül attól, hogy a Jupyter Notebook melyik könyvtárban van elindítva.
Lehetséges az os.chdir() használata a kódban az aktuális könyvtár megváltoztatására.

os.getcwd() és __file__.

Windowsban a pwd helyett a dir parancsot használhatja az aktuális könyvtár ellenőrzésére.

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

Hozzon létre egy Python script fájlt (file_path.py) a következő tartalommal az alsó szinten (data\src).

import os

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

Futtassa a python parancsot (vagy egyes környezetekben a python3 parancsot) a szkriptfájl elérési útvonalának megadásával.

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

Az aktuális könyvtár abszolút elérési útvonalát az os.getcwd() segítségével kaphatjuk meg. A python3 parancs által megadott elérési utat a __file__ használatával is megkaphatjuk.

A Python 3.8-ig a __file__ a python (vagy python3) parancsban megadott elérési utat tartalmazza. A fenti példában a relatív elérési utat adja vissza, mert az relatív, de az abszolút elérési utat adja vissza, ha az abszolút.

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

A Python 3.9 és újabb verziók a python (vagy python3) parancsban megadott elérési úttól függetlenül az __file__ abszolút elérési útját adja vissza.

A következő példában a kódot ugyanahhoz a szkriptfájlhoz (file_path.py) adjuk a Python 3.7-ben, és a fenti könyvtárhoz képest futtatjuk.

A Python 3.7-ben az abszolút elérési utat használjuk. Az eredményeket a szakasz végén mutatjuk be.

Az aktuálisan végrehajtott fájl fájlnevének és könyvtárnevének lekérdezése.

A futó fájl fájl- és könyvtárnevének lekérdezéséhez használja a következő függvényt a szabványos könyvtár os.path moduljában.

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

Végrehajtás eredménye.

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

A végrehajtandó fájl abszolút elérési útjának lekérdezése.

Ha a __file__ segítségével relatív elérési utat kapunk, akkor az os.path.abspath() segítségével abszolút elérési úttá alakítható. A könyvtárak abszolút elérési útvonalként is megkaphatók.

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

Végrehajtás eredménye.

# 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

Ha az os.path.abspath() függvényben abszolút elérési út van megadva, akkor az úgy fog visszakerülni, ahogy van. Ezért, ha a __file__ egy abszolút elérési útvonal, a következő nem okoz hibát.

  • os.path.abspath(__file__)

Más fájlok beolvasása az aktuálisan futó fájl helye alapján.

Ha a végrehajtott fájl helye (elérési útvonala) alapján más fájlokat is be akar olvasni, kösse össze a következő két fájlt az os.path.join() segítségével.

  • A végrehajtandó fájl könyvtára
  • A futó fájlból beolvasandó fájl relatív elérési útja.

Ha egy olyan fájlt szeretne beolvasni, amely ugyanabban a könyvtárban van, mint az éppen futó fájl, csak kapcsolja össze a fájl nevét.

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égrehajtás eredménye.

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

A felső szintet a “. \”. Hagyhatjuk úgy is, ahogy van, de az os.path.normpath() segítségével normalizálhatjuk az elérési utat, és eltávolíthatjuk az extra “. \” és más karaktereket.

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égrehajtás eredménye.

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

Az aktuális könyvtár áthelyezése a végrehajtandó fájl könyvtárába.

Az os.chdir() paranccsal az aktuális könyvtárat áthelyezheti a szkriptben végrehajtott fájl könyvtárába.

Láthatjuk, hogy az os.getcwd() mozgatja.

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

Végrehajtás eredménye.

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

Miután az aktuális könyvtárat áthelyeztük, a fájl olvasásakor nincs szükség a futó fájl könyvtárával való összekapcsolásra. Egyszerűen megadhatja a futó fájl könyvtárához viszonyított elérési utat.

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égrehajtás eredménye.

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

Ugyanaz a feldolgozás végezhető el az aktuális könyvtártól függetlenül futásidőben.

Amint azt már bemutattuk, lehetséges a fájlokat a szkriptfájl helye alapján betölteni, függetlenül a futáskori aktuális könyvtáraktól, az alábbi módszerek valamelyikével.

  • A futó fájl könyvtárának és a futó fájlból beolvasandó fájl relatív elérési útjának összekapcsolása az os.path.join() segítségével.
  • Az aktuális könyvtár áthelyezése a végrehajtandó fájl könyvtárába.

Egyszerűbb az aktuális könyvtárat áthelyezni, de természetesen, ha ezután további fájlokat akar olvasni vagy írni, figyelembe kell vennie, hogy az aktuális könyvtárat áthelyezték.

Az előző példák eredményeit az alábbiakban foglaljuk össze.

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

Az abszolút elérési út megadásának eredménye a következő.

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

Az aktuális könyvtár áthelyezésének eredménye a terminálban és ugyanannak a szkriptfájlnak a végrehajtása az alábbiakban látható. Látható, hogy ugyanazt a fájlt akkor is be lehet olvasni, ha más helyről hajtjuk végre.

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