pathlib: переносимая работа с путями и каталогами

Модуль pathlib представляет путь объектом, а не строкой с вручную подобранными разделителями. Оператор / добавляет компонент пути, методы отвечают за чтение, запись, поиск и…

Модуль pathlib представляет путь объектом, а не строкой с вручную подобранными разделителями. Оператор / добавляет компонент пути, методы отвечают за чтение, запись, поиск и создание каталогов, а свойства дают имя, суффикс и родительский каталог. Такой код переносимее между операционными системами и яснее отделяет путь от содержимого файла.

Построение пути без склейки строк

Path('reports') / '2026' / 'summary.txt' создаёт составной путь с правилами текущей платформы. Метод with_suffix заменяет расширение, stem возвращает имя без последнего суффикса, name — последний компонент. Объект Path может быть относительным: тогда файловая операция интерпретирует его от текущего рабочего каталога процесса, который не обязательно совпадает с каталогом исходного файла.

Создание каталога и работа с текстом

from pathlib import Path
from tempfile import TemporaryDirectory


with TemporaryDirectory() as directory:
    workspace = Path(directory)
    reports = workspace / 'reports' / 'daily'
    reports.mkdir(parents=True, exist_ok=True)

    report = reports / 'status.txt'
    report.write_text('alpha\nbeta\n', encoding='utf-8')

    print(report.name)
    print(report.suffix)
    print(report.read_text(encoding='utf-8').splitlines())
    print([path.name for path in reports.glob('*.txt')])

Ожидаемый результат

status.txt
.txt
['alpha', 'beta']
['status.txt']

parents=True разрешает создать отсутствующие родительские каталоги, а exist_ok=True не считает ошибкой уже существующий целевой каталог. Временный каталог удаляется после with, поэтому пример не оставляет следов. Для постоянных данных выберите явно заданный рабочий каталог.

Поиск и проверка типа объекта

glob('*.txt') ищет по шаблону на одном уровне, а rglob('*.txt') — рекурсивно. Результат — итератор путей, поэтому порядок файловой системы не следует считать стабильным; если он важен, примените sorted. Методы exists, is_file и is_dir отвечают на разные вопросы. Проверка exists не гарантирует, что следующий доступ пройдёт успешно: между операциями файл может исчезнуть или права могут измениться. Ошибки ввода-вывода всё равно нужно обрабатывать на подходящей границе.

Относительные, абсолютные и разрешённые пути

Path.cwd() показывает текущий рабочий каталог, а Path(__file__).resolve().parent часто используют как каталог модуля. resolve делает путь абсолютным и разрешает символические ссылки в соответствии с платформой. Не применяйте его автоматически при проверке пользовательского пути: сначала определите политику безопасности и допустимую корневую директорию.

Как диагностировать неверную базу пути

Частая ошибка — ожидать, что относительный путь начинается рядом со скриптом. При запуске из другой папки появляется FileNotFoundError. Выведите Path.cwd() и сам путь перед чтением, чтобы увидеть фактическую базу. Затем либо передавайте корень как параметр, либо стройте путь от явно выбранного каталога.

Другая ошибка — вызвать mkdir() для вложенной структуры без parents=True; тогда отсутствующий родитель вызывает FileNotFoundError. Если путь уже занят файлом, exist_ok=True не превратит его в каталог: проверьте is_file() и исправьте конфликт имён.

Практикум: рекурсивный поиск Markdown-файлов

Напишите функцию collect_markdown(root: Path) -> list[Path], которая рекурсивно находит только файлы с суффиксом .md и возвращает их в стабильном сортированном порядке. Создайте временное дерево из двух вложенных каталогов, двух Markdown-файлов и одного текстового. Самостоятельная проверка: функция должна вернуть ровно два пути; после смены текущего каталога результат не меняется, если передан абсолютный root; несуществующий корень обрабатывается согласно явно выбранному вами контракту.

Правила переносимой работы с Path

Path — структурированное представление пути. Компоненты соединяют оператором /, текст читают и пишут с явной кодировкой, каталоги создают с осознанными параметрами, а порядок результатов поиска при необходимости сортируют. Всегда различайте рабочий каталог процесса и каталог файла программы.

Вопросы о путях и файловой системе

Нужно ли преобразовывать Path в str?

Большинство современных функций стандартной библиотеки принимает path-like объекты напрямую. Преобразование требуется только API, которое действительно ожидает строку.

Чем glob отличается от rglob?

glob применяет переданный шаблон относительно текущего Path; rglob ищет с рекурсивным обходом подкаталогов.

Гарантирует ли exists успешное чтение?

Нет. Это снимок состояния на момент проверки. Само чтение может завершиться ошибкой из-за гонки, прав доступа или того, что путь оказался каталогом.

Источники