Отримання розташування (шляху) запущеного файлу в Python: __file__.

Бізнес

Щоб отримати розташування (шлях) запущеного файлу сценарію в Python, використовуйте __file__. Це корисно для завантаження інших файлів на основі розташування запущеного файлу.

До Python 3.8 __file__ повертає шлях, вказаний під час виконання команди python (або команди python3 у деяких середовищах). Якщо вказано відносний шлях, повертається відносний шлях; якщо вказано абсолютний шлях, повертається абсолютний шлях.

У Python 3.9 і пізніших версіях абсолютний шлях повертається незалежно від шляху, зазначеного під час виконання.

Пояснюється наступний зміст.

  • os.getcwd(),__file__
  • Отримайте ім’я файлу та ім’я каталогу поточно виконуваного файлу.
  • Отримайте абсолютний шлях до виконуваного файлу.
  • Зчитує інші файли на основі розташування поточного файлу.
  • Перемістити поточний каталог у каталог виконуваного файлу.
  • Таку ж обробку можна здійснити незалежно від поточного каталогу під час виконання.

Інформацію про отримання та зміну поточного каталогу (робочого каталогу) дивіться в наступній статті.

Зверніть увагу, що __file__ не можна використовувати в блокноті Jupyter (.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.

До Python 3.8 __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" !!