Список файлов в Python: от простого к сложному
Способы получения списка файлов в Python
Каким образом получить перечень файлов в директории, используя современные идиомы Python?
Наиболее эффективным и рекомендуемым решением является использование модуля pathlib, доступного начиная с Python 3.4. Он предоставляет объектно-ориентированный интерфейс для работы с путями.
from pathlib import Path
# Создание объекта Path для текущего каталога
folder = Path('.')
# Получение всех элементов (файлов и папок)
items = list(folder.iterdir())
# Фильтрация только файлов
files = [item for item in folder.iterdir() if item.is_file()]
# Фильтрация по расширению, например, только .txt
files_txt = list(folder.glob('*.txt'))
ввод программ на python (ввод данных в программе python)
Пояснение: метод iterdir() возвращает генератор объектов Path, представляющих содержимое каталога. Для отбора файлов используется метод is_file(). Метод glob() позволяет фильтровать по шаблону уже на уровне поиска.
Возможные проблемы: Если каталог не существует, будет выброшено исключение FileNotFoundError. Символические ссылки могут быть ошибочно идентифицированы как файлы или папки; для их разрешения используйте resolve(). На Windows могут возникать проблемы с правами доступа к некоторым системным каталогам.
Как получить простой список имён файлов без полного пути?
Используйте классическую функцию os.listdir():
import os
entries = os.listdir('.')
# entries содержит строки с именами
print(entries[:5])
Python file io (ввод-вывод файлов в python)
Этот метод возвращает список строк, представляющих имена всех элементов в указанном каталоге. Недостаток: нет информации о типе элемента (файл или папка), для проверки требуется дополнительный вызов os.path.isdir() или os.path.isfile().
Типичная ошибка: путаница между относительными и абсолютными путями. Например, os.listdir('subdir') работает только если подкаталог существует относительно текущей рабочей директории.
Как получить список файлов, соответствующих определённому шаблону (например, все изображения)?
Модуль glob предоставляет возможности поиска по шаблону:
import glob
# Все .jpg файлы в текущей папке
jpg_files = glob.glob('*.jpg')
# Рекурсивный поиск (Python 3.5+)
all_images = glob.glob('**/*.jpg', recursive=True)
Python temp files (временные файлы в python)
Шаблоны поддерживают стандартные символы: * (любая последовательность символов, кроме разделителя), ? (один символ), [...] (диапазон). Параметр recursive=True включает обход всех подкаталогов.
Внимание: glob не различает файлы и папки. Если нужны только файлы, придётся дополнительно проверять через os.path.isfile(). На больших деревьях рекурсивный обход может быть медленным.
Как рекурсивно обойти все подкаталоги и получить полные пути к файлам?
Функция os.walk() генерирует имена файлов в дереве каталогов:
import os
for root, dirs, files in os.walk('.'):
for file in files:
full_path = os.path.join(root, file)
print(full_path)
Python index files (индексация файлов в python)
Переменная root содержит текущий обрабатываемый путь, dirs – список подкаталогов, files – список файлов. Можно модифицировать dirs на ходу, чтобы исключить некоторые подкаталоги.
Сложность: os.walk() использует много памяти при глубокой вложенности? На практике генератор не накапливает все данные, но скорость может быть ниже, чем у scandir.
Какой способ быстрее, если требуется только список имён файлов в одной директории?
Использование os.scandir() (Python 3.5+):
import os
with os.scandir('.') as entries:
files = [entry.name for entry in entries if entry.is_file()]
Метод scandir() возвращает итератор объектов DirEntry, которые при необходимости предоставляют дополнительную информацию (тип, размер, время модификации) без лишних системных вызовов.
Замечание: В Python 3.12+ os.scandir() поддерживает параметр follow_symlinks=False для игнорирования символических ссылок.
Расширенные примеры работы со списками файлов
1. Получение списка файлов с фильтрацией по расширению и дате изменения
Пример объединяет модули pathlib и datetime:
from pathlib import Path
from datetime import datetime, timedelta
folder = Path('/var/log')
# Файлы, изменённые за последние 24 часа с расширением .log
recent_logs = [
f for f in folder.glob('*.log')
if datetime.fromtimestamp(f.stat().st_mtime) > datetime.now() - timedelta(days=1)
]
print(recent_logs)
[WindowsPath('C:/var/log/syslog'), WindowsPath('C:/var/log/auth.log')]
2. Рекурсивный сбор файлов с исключением определённых папок
Используя os.walk() с модификацией списка dirs:
import os
for root, dirs, files in os.walk('.'):
# Исключаем папки .git и __pycache__
dirs[:] = [d for d in dirs if d not in ('.git', '__pycache__')]
for file in files:
if file.endswith('.py'):
print(os.path.join(root, file))
.\main.py .\utils\helpers.py .\tests\test_main.py
3. Сортировка списка файлов по размеру
Метод sorted() с ключом от Path.stat():
from pathlib import Path
folder = Path('/tmp')
files = [f for f in folder.iterdir() if f.is_file()]
files_sorted = sorted(files, key=lambda f: f.stat().st_size, reverse=True)
for f in files_sorted[:3]:
print(f.name, f.stat().st_size)
large_file.bin 104857600 medium.txt 2048000 small.txt 1024
4. Генерация списка файлов с отбором по регулярному выражению
Совместное применение re и os.listdir():
import os, re
pattern = re.compile(r'^data_\d{4}-\d{2}\.csv$')
matching = [f for f in os.listdir('.') if pattern.match(f)]
print(matching)
['data_2023-01.csv', 'data_2023-02.csv']
5. Обработка ошибок доступа при рекурсивном обходе
Использование os.scandir() с блоком try/except PermissionError:
import os
def list_files_safe(path):
try:
with os.scandir(path) as it:
for entry in it:
if entry.is_file(follow_symlinks=False):
yield entry.path
elif entry.is_dir(follow_symlinks=False):
yield from list_files_safe(entry.path)
except PermissionError:
# Пропускаем недоступные директории
pass
for f in list_files_safe('/'):
print(f)
/root/.bashrc /var/log/syslog ...
6. Получение списка файлов с полными абсолютными путями (метод resolve)
Преобразование относительных путей в абсолютные:
from pathlib import Path
folder = Path('.')
absolute_files = [f.resolve() for f in folder.glob('**/*.txt')]
print(absolute_files[:2])
[WindowsPath('C:/Users/User/Documents/example.txt'), WindowsPath('C:/Users/User/Documents/note.txt')]
7. Параллельный обход каталогов с помощью pathlib.rglob
Метод rglob() эквивалентен рекурсивному glob:
from pathlib import Path
for py_file in Path('src').rglob('*.py'):
if py_file.stat().st_size > 10000:
print(f'{py_file}: {py_file.stat().st_size} bytes')
src/main.py: 15000 bytes src/utils.py: 12000 bytes