Получаване на местоположението (пътя) на текущ файл в Python: __file__.

Бизнес

За да получите информация за местоположението (пътя) на изпълняван скрипт в Python, използвайте __file__. Това е полезно за зареждане на други файлове въз основа на местоположението на текущия файл.

До версия 3.8 на Python __file__ връща пътя, посочен при изпълнение на командата python (или python3 в някои среди). Ако е посочен относителен път, се връща относителният път; ако е посочен абсолютен път, се връща абсолютният път.

В Python 3.9 и по-нови версии се връща абсолютният път, независимо от пътя, зададен по време на изпълнение.

Обяснено е следното съдържание.

  • os.getcwd(),__file__
  • Получаване на името на файла и името на директорията на текущо изпълнявания файл.
  • Получаване на абсолютния път на изпълнявания файл.
  • Чете други файлове въз основа на местоположението на текущо изпълнявания файл.
  • Преместване на текущата директория в директорията на изпълнявания файл.
  • Една и съща обработка може да се извърши независимо от текущата директория по време на изпълнение.

Вижте следната статия за информация относно получаването и промяната на текущата директория (работна директория).

Имайте предвид, че __file__ не може да се използва в Jupyter Notebook (.ipynb).
Директорията, в която се намира .ipynb, ще бъде изпълнена като текуща директория, независимо от директорията, в която е стартиран Jupyter Notebook.
Възможно е да използвате os.chdir() в кода, за да промените текущата директория.

os.getcwd() и __file__.

В Windows можете да използвате командата dir вместо pwd, за да проверите текущата директория.

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

Създайте скриптов файл на Python (file_path.py) със следното съдържание в долното ниво (data\src).

import os

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

Изпълнете командата python (или командата python3 в някои среди), като посочите пътя до файла със скрипта.

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

Абсолютният път до текущата директория може да се получи с os.getcwd(). Можете също така да използвате __file__, за да получите пътя, зададен от командата python3.

До версия 3.8 на Python __file__ съдържа пътя, посочен в командата python (или python3). В примера по-горе се връща относителният път, защото е относителен, но се връща абсолютният път, ако е абсолютен.

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 и по-нови версии връщат абсолютния път до __file__, независимо от пътя, посочен в командата python (или python3).

В следващия пример ще добавим кода към същия скриптов файл (file_path.py) в Python 3.7 и ще го стартираме спрямо горната директория.

В Python 3.7 се използва абсолютният път. Резултатите са показани в края на този раздел.

Получаване на името на файла и името на директорията на текущо изпълнявания файл.

За да получите името на файла и името на директорията на изпълнявания файл, използвайте следната функция в модула os.path на стандартната библиотека.

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

Резултат от изпълнението.

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

Получаване на абсолютния път на изпълнявания файл.

Ако е получен относителен път с помощта на __file__, той може да бъде превърнат в абсолютен път с os.path.abspath(). Директориите също могат да бъдат получени като абсолютни пътища.

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

Резултат от изпълнението.

# 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

Ако в os.path.abspath() е зададен абсолютен път, той ще бъде върнат в този вид. Следователно, ако __file__ е абсолютен път, следното няма да доведе до грешка.

  • os.path.abspath(__file__)

Чете други файлове въз основа на местоположението на текущо изпълнявания файл.

Ако искате да прочетете други файлове въз основа на местоположението (пътя) на изпълнявания файл, съединете следните два файла с помощта на os.path.join().

  • Директория на изпълнявания файл
  • Относителен път до файла, който ще бъде прочетен от текущия файл.

Ако искате да прочетете файл в същата директория, в която се намира изпълняваният файл, просто конкатенирайте името на файла.

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

Резултат от изпълнението.

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

Горното ниво е представено с „. \“. Можете да го оставите така, както е, но можете да използвате os.path.normpath(), за да нормализирате пътя и да премахнете допълнителните „. \“ и други символи.

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

Резултат от изпълнението.

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

Преместване на текущата директория в директорията на изпълнявания файл.

Използвайте os.chdir(), за да преместите текущата директория в директорията на файла, който се изпълнява в скрипта.

Можете да видите, че тя е преместена от os.getcwd().

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

Резултат от изпълнението.

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

След като текущата директория е преместена, не е необходимо да я свързвате с директорията на текущия файл при четене на файла. Можете просто да посочите пътя спрямо директорията на текущия файл.

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

Резултат от изпълнението.

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

Една и съща обработка може да се извърши независимо от текущата директория по време на изпълнение.

Както показахме, възможно е да се зареждат файлове въз основа на местоположението на файла на скрипта, независимо от текущата директория по време на изпълнение, като се използва един от следните методи.

  • Свържете директорията на текущия файл и относителния път до файла, който ще бъде прочетен от текущия файл, като използвате os.path.join().
  • Преместване на текущата директория в директорията на изпълнявания файл.

По-лесно е да преместите текущата директория, но, разбира се, ако след това искате да четете или записвате повече файлове, трябва да вземете предвид, че текущата директория е преместена.

Резултатите от предишните примери са обобщени по-долу.

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

Резултатът от посочването на абсолютния път е следният.

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

Резултатът от преместването на текущата директория в терминала и изпълнението на същия скриптов файл е показан по-долу. Виждате, че същият файл може да бъде прочетен, дори и да бъде изпълнен от друго място.

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