Открытие и обход директорий в Python: подробные инструкции с примерами
Открытие директории в Python: обзор методов и решений
Наиболее современным и удобным способом открытия директории для чтения её содержимого является использование модуля pathlib. Этот подход рекомендуется для нового кода, так как он предлагает объектно-ориентированный интерфейс для работы с путями и автоматически обрабатывает различия между операционными системами.
Как получить список файлов и подпапок в директории с помощью pathlib?
from pathlib import Path
directory = Path('/путь/к/директории')
for entry in directory.iterdir():
print(entry.name)Python open directory (открытие директории в python)
Метод iterdir() возвращает итератор объектов Path, представляющих каждый элемент внутри директории. Это экономит память при работе с большими папками. Каждый объект Path предоставляет доступ к атрибутам: .name (имя файла/папки), .is_file(), .is_dir() и др.
Типичные ошибки:
- FileNotFoundError - директория не существует. Решение: перед вызовом iterdir() проверить directory.exists().
- PermissionError - недостаточно прав. Решение: обработать исключение или проверить доступ через os.access().
- Симлинки могут повторяться или вести в несуществующие места. Можно использовать .resolve() для получения реального пути.
Как открыть директорию через os.listdir() для простого списка имён?
import os
entries = os.listdir('/путь/к/директории')
for entry in entries:
print(entry)
Функция os.listdir() возвращает список строк - имён файлов и папок. Это простой и быстрый способ, но он не даёт информации о типе элемента (файл или папка). Чтобы различить их, приходится дополнительно вызывать os.path.isdir() или os.path.isfile().
Проблемы: при большом количестве файлов список занимает всю память; кодировка имён может вызвать ошибки в не-ASCII именах; отсутствие информации о типе.
Как получить расширенные атрибуты файлов с помощью os.scandir()?
import os
with os.scandir('/путь/к/директории') as entries:
for entry in entries:
print(entry.name, entry.is_file(), entry.stat().st_size)
os.scandir() возвращает итератор объектов DirEntry, которые содержат методы .is_file(), .is_dir(), .stat() и др., причём эта информация часто получается без дополнительного системного вызова. Это эффективнее, чем os.listdir() + os.stat().
Типичные ошибки: забыть использовать контекстный менеджер with - тогда ресурсы не освободятся. Объект DirEntry становится недействительным после завершения итерации.
Как найти файлы по шаблону с помощью glob.glob()?
import glob
for filepath in glob.glob('/путь/к/директории/*.txt'):
print(filepath)
Модуль glob позволяет искать файлы, соответствующие шаблону (с подстановочными символами *, ?, [abc]). Возвращает список полных путей. Полезно для фильтрации по расширению или имени.
Проблема: glob.glob() загружает все результаты в память. Для очень больших папок рекомендуется pathlib.Path.glob() или glob.iglob(), который возвращает итератор.
Как рекурсивно обойти все поддиректории с os.walk()?
import os
for root, dirs, files in os.walk('/путь/к/директории'):
for file in files:
print(os.path.join(root, file))
os.walk() рекурсивно обходит дерево каталогов, возвращая кортежи (путь к текущей папке, список подпапок, список файлов). Это классический способ для задач, требующих обхода всех вложенных папок.
Ошибки: если в процессе обхода в папке появляются или удаляются элементы, поведение может быть непредсказуемым. Модифицировать списки dirs и files во время итерации - допустимо, но осторожно.
Расширенные примеры работы с открытием директории
Пример 1: Фильтрация файлов по размеру и дате с pathlib
from pathlib import Path
import time
directory = Path('/tmp/test_dir')
for entry in directory.iterdir():
if entry.is_file():
stat = entry.stat()
if stat.st_size > 1024 and stat.st_mtime > time.time() - 86400:
print(f'{entry.name}: {stat.st_size} bytes, modified {time.ctime(stat.st_mtime)}')
(вывод будет содержать файлы размером более 1 КБ, изменённые за последние сутки)
Пример 2: Рекурсивный обход с pathlib.rglob()
from pathlib import Path
for py_file in Path('/проект').rglob('*.py'):
print(py_file)
/проект/main.py /проект/src/utils.py /проект/tests/test_main.py
Метод rglob() выполняет рекурсивный поиск по шаблону, аналогичный glob.glob('**/*.py').
Пример 3: Открытие директории с обработкой исключений
from pathlib import Path
def safe_iterdir(path_str):
p = Path(path_str)
if not p.exists():
raise FileNotFoundError(f"Директория не существует: {path_str}")
if not p.is_dir():
raise NotADirectoryError(f"Путь не является директорией: {path_str}")
try:
return list(p.iterdir())
except PermissionError as e:
print(f"Нет доступа к {path_str}: {e}")
return []
entries = safe_iterdir('/недоступная_папка')
Пример 4: Использование os.scandir для копирования всех файлов размера больше 10 МБ
import os
import shutil
dest_dir = '/backup'
with os.scandir('/source') as entries:
for entry in entries:
if entry.is_file() and entry.stat().st_size > 10 * 1024 * 1024:
shutil.copy2(entry.path, os.path.join(dest_dir, entry.name))
(файлы скопированы без вывода, если не возникнет ошибок)
Пример 5: Проверка на символические ссылки с помощью pathlib
from pathlib import Path
for entry in Path('/смешанная_папка').iterdir():
if entry.is_symlink():
print(f'{entry.name} -> {entry.resolve()}')
link_to_docs -> /real/path/to/docs
Пример 6: Получение полной информации о каждого файла с os.stat()
import os
, time
for name in os.listdir('/папка'):
full = os.path.join('/папка', name)
if os.path.isfile(full):
s = os.stat(full)
print(f'{name} | size: {s.st_size} | mtime: {time.ctime(s.st_mtime)} | mode: {oct(s.st_mode)}')
file1.txt | size: 1234 | mtime: Thu Sep 21 10:00:00 2024 | mode: 0o100644