Список файлов в 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 для игнорирования символических ссылок.

- Python config files (конфигурационные файлы в python)
- Python copy file (копирование файла в python)
- Python log file (логирование в файл в python)

Расширенные примеры работы со списками файлов

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

Список файлов в Python - comments

En
Python file list (python)