Глава 15 · Python и файлы

Текущая рабочая директория — CWD

Один из самых частых источников файловых ошибок: относительный путь ведёт не туда, куда вы думали.

Текущая рабочая директория (CWD)

Узнать текущую рабочую директорию программы:

cwd.py
from pathlib import Path

print(Path.cwd())

Текущая рабочая директория (CWD) — это папка, относительно которой интерпретируются обычные относительные пути в программе.

CWD — это НЕ «папка со скриптом»
Это одна из самых частых ошибок с путями в реальном коде. CWD и папка, где лежит файл .py, могут совпадать — а могут и не совпадать. CWD определяется тем, откуда была запущена программа, а не тем, где физически лежит её исходный файл.
project/ ← CWD (запуск python src/app.py отсюда)
src/
app.py
data/
config.json
Скрипт лежит в src/app.py, но CWD — это project/, если запустить программу отсюда.
app_py_fragment.py
# внутри src/app.py, если программа запущена из project/:
from pathlib import Path

путь = Path("data/config.json")
# указывает на project/data/config.json — НЕ на project/src/data/config.json
Debug Lab 2: CWD — это не папка со скриптом
app_wrong.py
# файл лежит в project/src/app.py
from pathlib import Path

config = Path("config.json")   # предполагаем: "рядом со скриптом"
print(config.read_text(encoding="utf-8"))
$ cd project
$ python src/app.py
Traceback (most recent call last):
FileNotFoundError: [Errno 2] No such file or directory: 'config.json'
Что видно на экране

Файл config.json лежит в project/src/, рядом со скриптом. Но программа запущена из project/ — значит, CWD равен project/, и относительный путь "config.json" ищется в project/config.json, которого нет.

Исправленный код
app_fixed.py
# надёжный способ — путь относительно самого файла, а не относительно CWD
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent
config = BASE_DIR / "config.json"
print(config.read_text(encoding="utf-8"))

Папка скрипта: __file__

Для обычных .py-файлов узнать папку, где лежит сам исходный файл, можно так:

script_dir.py
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent
__file__ не гарантирован всегда
__file__ обычно определён в обычных скриптах и модулях, но интерактивная оболочка Python и некоторые окружения ноутбуков могут не задавать эту переменную. Не считайте её универсально доступной в любом контексте выполнения кода.
Практика: CWD и папка скрипта на вашем компьютере
Локальная практика — запустите настоящий .py-файл из разных папок и понаблюдайте, что меняется
Практика выполняется локально
Открыть практику →