За да получите информация за местоположението (пътя) на изпълняван скрипт в 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__.
- Получаване на името на файла и името на директорията на текущо изпълнявания файл.
- Получаване на абсолютния път на изпълнявания файл.
- Чете други файлове въз основа на местоположението на текущо изпълнявания файл.
- Преместване на текущата директория в директорията на изпълнявания файл.
- Една и съща обработка може да се извърши независимо от текущата директория по време на изпълнение.
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" !!