Рекурсивное чтение файлов из подпапок на Python
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Функция os.walk()
– это удобный инструмент для обхода директорий в Python. Пример ниже показывает, как вывести список всех файлов в указанной директории:
import os
for dirpath, _, filenames in os.walk('./target_dir'):
for filename in filenames:
print(os.path.join(dirpath, filename))
Замените './target_dir'
на путь до необходимой вам директории. Данный код возвращает абсолютные пути всех файлов, рекурсивно пройдя по всем поддиректориям.
Рекомендации по оптимизации
Функция os.walk()
весьма функциональна, но при ее использовании стоит быть внимательным. Вот несколько полезных советов:
- Динамические пути: дабы преобразовать относительные пути в абсолютные, используйте
os.path.abspath()
. - Работа с файлами: для управления файлами рекомендуется использовать конструкцию
with
, она обеспечивает их корректное закрытие. - Избегание конфликтов имен: не давайте переменной имя
file
, чтобы не перекрывать встроенные типы. - Конкатенация путей: при работе с путями лучше всего использовать
os.path.join()
, а не операцию складывания строк. - Фильтрация файлов: для фильтрации файлов по расширению удобно использовать
glob.iglob()
с шаблоном'**'
(эта возможность доступна, начиная с Python 3.5).
Пример оптимизированного кода:
import os
import glob
# Переменная start_dir будет содержать абсолютный путь
start_dir = os.path.abspath('./target_dir')
# Используем glob для поиска всех текстовых файлов
for file_path in glob.iglob(start_dir + '**/*.txt', recursive=True):
with open(file_path, 'r') as f:
# Выводим сообщение о текущем файле
print(f'Обработываю файл: {file_path}')
Такой код обслуживается легко и ясно для понимания.
Взаимодействие с Pathlib
С версии Python 3.4 доступен модуль pathlib
, предлагающий объектно-ориентированный подход к работе с файловыми системами. Давайте модифицируем предыдущий пример с использованием pathlib
:
from pathlib import Path
# Получаем абсолютный путь с помощью метода Path.resolve()
start_dir = Path('./target_dir').resolve()
# С pathlib нам не нужен glob.iglob!
for file_path in start_dir.rglob('*.txt'):
with file_path.open('r') as f:
# Читаем и обрабатываем файлы
print(f'Обработываю файл: {file_path}')
Использование pathlib
делает код более обтекаемым и стильным.
Экспертное взаимодействие с вводом/выводом
Обход каталогов – это только начало, вам, как правило, придется работать непосредственно с файлами. Вот несколько проверенных практик:
- Режимы файлов: всегда явно указывайте режим файла при его открытии (например,
'r', 'w'
). - Обработка ошибок: используйте блоки try-except для отлова исключений, связанных с вводом/выводом.
- Управление ресурсами: блок
with
гарантирует автоматическое освобождение ресурсов после использования файла.
Пример применения:
try:
with Path('./target_dir/file.txt').open('r') as f:
# Чтение данных из файла
data = f.read()
except IOError as e:
# Обработка возможных ошибок ввода/вывода
print(f'Не удалось прочитать файл! Ошибка ввода/вывода: {e.strerror}')
Визуализация
В наглядной форме рекурсивное чтение папок в Python можно представить как многослойный артишок:
🌻 КОРНЕВАЯ ПАПКА
|
├─🍃 Папка А (разворачиваем слой, обнаруживаем содержимое)
| ├─📄 Файл1
| └─🌿 Подпапка А1 (проникаем глубже)
| ├─📄 Файл2
| └─📄 Файл3
|
├─🍃 Папка В
| └─📄 Файл4
|
└─🍂 Папка С (иногда увядшие листья вполне содержательны)
└─🌿 Подпапка С1
└─📄 Файл5
Также как артишок открывает свои слои, рекурсия позволяет нам глубже проникать в структуру каталогов.
Безопасный и эффективный обход
Для обеспечения безопасности и эффективности стоит придерживаться следующих рекомендаций:
- Абсолютные пути: используйте
os.path.abspath()
для безопасной обработки путей, переданных как аргументы командной строки. - Проверка существования: перед работой с путями проверьте их наличие с помощью
os.path.exists()
илиPath.exists()
. - Производительность: при обходе глубоких структур каталогов сравните производительность методов
os.walk()
,os.scandir()
иpathlib
, чтобы выбрать наиболее эффективный.
Следуя этим принципам, вы добьетесь не только корректности, но и высокой производительности кода!
Продвинутые шаблоны glob
Begin from Python 3.5 to filter files by extension, you can use recursive=True
:
# Пример использования glob для поиска всех python-файлов
for file_path in Path('.').rglob('*.py'):
# Выводим путь к файлу
print(file_path)
Не забывайте, что завершающий слеш '/' в путях обеспечивает точное соответствие шаблону.
Полезные ссылки
- os — разнообразные интерфейсы операционной системы — документация Python 3.12.2 — официальная документация функции
os.walk()
, которую необходимо изучить для работы с директориями в Python. - python – Как рекурсивно искать подпапки и добавить файлы в список? – Stack Overflow — обсуждения и примеры рекурсивного поиска в директориях от сообщества разработчиков.
- Метод os.walk() Python – Tutorialspoint — понятное руководство о том, как использовать
os.walk()
для навигации по файловым системам. - glob — расширение путей в стиле Unix — документация Python 3.12.2 — подробная документация по работе с файлами с применением шаблонов, часто используемых для рекурсивного поиска.
- Рекурсивное мышление в Python – Real Python — статья на Real Python, которая помогает понять концепцию рекурсии в Python для изучения рекурсивных функций.
- Модуль pathlib Python: укрощение файловой системы – Real Python — статья о том, как использовать
pathlib
как современный инструмент для работы с файловыми системами, применимый и для рекурсивных задач. - Эффективный обход файловой системы в Python: os.walk против os.scandir – Medium — сравнение методов
os.walk
иos.scandir
с точки зрения производительности при работе с файловыми системами.