Программирование19 октября 2026 г.

Как составить безопасный план обработки файлов с pathlib

Автор
Ненашев А.
На чтение
7 мин
Дата обновления
19.10.2026
Старт:С 23 ноября
Срок обучения:32 часа
Прикладной Python для ИТ-специалистов + ИИ-инструменты
Курс для ИТ-специалистов, которые пишут скрипты на Python и хотят перейти к надёжным, поддерживаемым решениям. В программе: управление зависимостями, типизация, линтеры, тесты, работа с файлами и API, отладка, анализ производительности коллекций. 60 % времени — практика: от разового скрипта до CLI-утилиты с тестами. Отдельно — безопасное использование ИИ-ассистентов в работе с кодом.
Подробнее
1 497 ₽44 900 ₽
#COURSE##INNER#

Как составить безопасный план обработки файлов с pathlib

Если в папке лежат CSV-файлы, рядом есть вложенный каталог и временный файл, самая частая ошибка — сразу переходить к чтению или изменению содержимого. Безопаснее сначала построить план обработки: отдельно показать, какие элементы подходят, какие исключаются и почему, а уже потом решать, нужен ли следующий шаг. В этой статье разберем именно такой первый проход с pathlib, без удалений, перемещений и перезаписи.

Ниже будет один условный учебный кейс с проверяемым результатом. Его цель простая: пройтись по папке, взять только подходящие обычные CSV-файлы верхнего уровня, исключить каталог и временный файл, а в конце получить итоговое число. Такой подход полезен не только новичку: он делает поведение скрипта понятным еще до любых действий с данными.

Какие файлы вообще входят в задачу

Для безопасного плана сначала нужно сузить границы задачи. В нашем случае мы не обходим дерево рекурсивно, а смотрим только на содержимое одной папки. Это важно: если внутри есть вложенный каталог, его наличие фиксируем как исключение, но файлы внутри него пока не рассматриваем. Так вы не смешаете текущую выгрузку с архивом, черновиками или чужими подпапками.

Учебный пример. Пусть у нас есть папка incoming со следующим содержимым:

incoming/
├── clients.csv
├── orders_2026-10.csv
├── ~$orders_2026-10.csv
└── archive/
    └── old_orders.csv

Здесь ожидаемое решение такое: clients.csv и orders_2026-10.csv входят в план, потому что это обычные файлы с расширением .csv. Элемент archive не входит, потому что это каталог. Файл ~$orders_2026-10.csv не входит, хотя заканчивается на .csv, потому что по имени похож на временный. Такая явная классификация лучше, чем правило вида «брать все CSV подряд».

ЭлементРешениеПричина
clients.csvВключитьОбычный CSV-файл
orders_2026-10.csvВключитьОбычный CSV-файл
~$orders_2026-10.csvИсключитьВременный файл по имени
archiveИсключитьЭто каталог, а не файл

Обход папки и явные условия отбора

Для такого плана удобно использовать Path.iterdir(): он дает элементы текущей папки по одному. Здесь полезно не сокращать правила слишком рано. Когда условия отбора написаны по шагам, вы сразу видите порядок решений: сначала проверить, что перед вами не ссылка, потом что это обычный файл, потом что он не скрытый и не временный, и только после этого — что он действительно CSV.

Ниже пример функции, которая ничего не меняет в файловой системе. Она только возвращает структуру с подходящими файлами, исключениями и итоговым количеством. Код рассчитан на обычный запуск в Python с модулем pathlib.

from pathlib import Path

TEMP_ENDINGS = (".tmp", ".temp", ".part", "~")

def is_temporary_file(path: Path) -> bool:
    name = path.name.lower()
    return name.startswith("~$") or name.endswith(TEMP_ENDINGS)


def build_processing_plan(root: Path) -> dict[str, object]:
    if not root.exists():
        raise FileNotFoundError(f"Папка не найдена: {root}")
    if not root.is_dir():
        raise NotADirectoryError(f"Это не папка: {root}")

    suitable: list[str] = []
    excluded: list[str] = []

    for path in sorted(root.iterdir(), key=lambda p: p.name.lower()):
        if path.is_symlink():
            excluded.append(f"{path.name} — ссылка")
            continue
        if not path.is_file():
            excluded.append(f"{path.name} — не обычный файл")
            continue
        if path.name.startswith("."):
            excluded.append(f"{path.name} — скрытый файл")
            continue
        if is_temporary_file(path):
            excluded.append(f"{path.name} — временный файл")
            continue
        if path.suffix.lower() != ".csv":
            excluded.append(f"{path.name} — не CSV")
            continue

        suitable.append(path.name)

    return {
        "suitable": suitable,
        "excluded": excluded,
        "total": len(suitable),
    }

Обратите внимание на две детали. Во-первых, сортировка делает вывод повторяемым: список не «прыгает» от запуска к запуску. Во-вторых, проверка path.suffix стоит ближе к концу, потому что тип элемента важнее расширения. Каталог с точкой в имени все равно не должен попасть в список файлов на обработку.

Проверка списка до любых изменений

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

Для нашего учебного примера результат должен быть таким:

Подходящие файлы:
- clients.csv
- orders_2026-10.csv

Исключения:
- ~$orders_2026-10.csv — временный файл
- archive — не обычный файл

Итоговое число: 2

Проверяемый результат учебного примера: подходящих файлов ровно 2. Это число согласовано с исходным набором: в верхней папке лежат два обычных CSV, один временный файл и один каталог. Файл old_orders.csv внутри archive в счет не идет, потому что текущий план не рекурсивный.

Полезно продумать и граничные случаи. Если в папке нет CSV верхнего уровня, итог будет 0, и это нормальный результат, а не ошибка классификации. Если все элементы оказались исключениями, такой отчет тоже полезен: он показывает, что скрипт не пропустил данные «молча», а честно объяснил, почему никого не включил.

Скрытые файлы и ссылки как отдельные решения

Скрытые файлы лучше рассматривать отдельно, даже если они подходят по расширению. Причина практическая: файл вида .draft.csv может оказаться черновиком, служебным артефактом редактора или просто заготовкой, которую не собирались включать в обработку. Если добавить правило path.name.startswith('.'), вы не потеряете его из виду, но и не включите случайно.

Со ссылками логика похожая. Ссылка может выглядеть как удобный ярлык на нужный CSV, но в безопасном плане лучше сначала пометить ее как отдельный тип элемента. Тогда решение «обрабатывать ли ссылки» принимается явно, а не прячется внутри общей проверки файлов. Это особенно полезно, когда данные лежат в общей папке и вы не хотите неявно подтягивать содержимое из другого места.

Допустим, в тот же учебный каталог добавили еще два элемента:

incoming/
├── .draft.csv
├── current.csv -> orders_2026-10.csv

Тогда безопасный план по-прежнему может оставить подходящими только два файла: clients.csv и orders_2026-10.csv. Исключения расширятся до четырех: временный файл, каталог, скрытый файл и ссылка. Итоговое число не изменится, потому что мы сознательно не смешиваем «обычный CSV» с отдельными спорными случаями.

Как превратить такой план в рабочую привычку

Удобная схема состоит из трех шагов: собрать список, проверить его, только потом запускать следующий этап. Даже если дальше вам нужно только читать CSV, не пропускайте первый шаг. Он отлавливает самые неприятные ошибки: случайную рекурсию по подпапкам, попадание временных файлов, захват скрытых черновиков и неявную работу со ссылками.

Практический итог этой статьи можно сформулировать так: безопасный план обработки файлов — это не «прочитать все, что похоже на CSV», а заранее описать и показать правила отбора. В учебном примере это дало прозрачный результат: два подходящих файла, список исключений с причинами и понятное итоговое число. Такой отчет легко проверить вручную, а позже — покрыть тестом, если вы будете повторять эту задачу регулярно.

  • Не обходите подпапки по умолчанию, если задача сформулирована только для одной директории.
  • Проверяйте тип элемента до проверки расширения.
  • Временные, скрытые файлы и ссылки лучше выделять отдельными правилами.
  • Сначала получайте план, и только потом решайте, нужен ли этап чтения файлов.

Если хотите потренировать тему дальше

Во внутренней карточке каталога курса есть программа по прикладному Python. На официальной странице школы для этого курса подтверждены темы, напрямую полезные для такого задания: работа с файловой системой через pathlib, чтение .csv, обработка исключений, а также базовое тестирование на pytest. Для темы этой статьи это ценно тем, что безопасный план удобно не только написать, но и проверить автотестом на небольшом учебном наборе файлов.

Курсы

147571
0,0
0 отзывов
Прикладной Python для ИТ-специалистов + ИИ-инструменты
  • С 23 ноября
  • 32 часа
  • с преподавателем
  • сертификат
1 497 ₽44 900 ₽
-97%
Перейти на сайт