Операции с файловой системой в Python с помощью стандартных библиотек
Основные возможности os и shutil для работы с файловой системой
Модули os и shutil предоставляют функции для взаимодействия с операционной системой: управление файлами, каталогами, путями, правами доступа. Они входят в стандартную библиотеку Python и подходят для задач администрирования, резервного копирования, обработки данных. Ниже рассмотрены типовые операции с примерами кода.
Эффективная комбинация: os.scandir, os.makedirs, shutil.copy2, shutil.rmtree
Как получить список файлов и папок с метаданными, создать вложенные каталоги, скопировать содержимое с сохранением атрибутов и удалить дерево?
Используйте os.scandir вместо os.listdir, чтобы сразу получать объекты DirEntry с информацией о типе, размере, времени изменения. Для создания многоуровневых каталогов применяйте os.makedirs с флагом exist_ok=True. Копируйте файлы с помощью shutil.copy2, сохраняя метаданные. Для удаления непустых каталогов вызывайте shutil.rmtree.
import os
import shutil
# Получение содержимого папки
for entry in os.scandir('/path/to/dir'):
if entry.is_file():
print(f'Файл: {entry.name}, размер: {entry.stat().st_size} байт')
elif entry.is_dir():
print(f'Папка: {entry.name}')
# Создание вложенных каталогов
os.makedirs('/new/dir/a/b/c', exist_ok=True)
# Копирование файла с метаданными
shutil.copy2('source.txt', 'dest.txt')
# Удаление дерева каталогов
shutil.rmtree('/path/to/dir')Python run exe file (запуск exe-файла из python)
Какие ошибки возможны при использовании shutil.rmtree?
При отсутствии прав доступа к удаляемым объектам возникает PermissionError. Если каталог является частью монтирования или занят процессом, удаление может завершиться ошибкой. Рекомендуется заключать вызов в блок try-except. Также shutil.rmtree не различает символические ссылки и обрабатывает их как обычные файлы, что может привести к удалению целевого объекта ссылки.
Вариант 1: os.listdir для простого списка имён
Как быстро получить только имена объектов в каталоге без метаданных?
Функция os.listdir возвращает список строк. Это удобно для простых сценариев, но требует последующих вызовов os.path для проверки типа и свойств. Может быть медленнее на больших директориях.
import os
for name in os.listdir('/path'):
full = os.path.join('/path', name)
if os.path.isfile(full):
print(f'Файл: {name}')
elif os.path.isdir(full):
print(f'Папка: {name}')Python send files (отправка файлов в python)
Почему os.listdir может не подойти для глубокого обхода?
Он не рекурсивен и не предоставляет информацию о размере или времени. Для вложенных структур требуется дополнительный код или os.walk.
Вариант 2: os.walk для рекурсивного обхода
Как пройти всё дерево каталогов, обработать файлы в каждой папке?
os.walk генерирует кортежи (путь, подкаталоги, файлы) для каждой ветви. Это стандартный способ обойти большое дерево без написания собственной рекурсии.
import os
for root, dirs, files in os.walk('/top'):
for f in files:
fpath = os.path.join(root, f)
size = os.path.getsize(fpath)
print(f'{fpath}: {size} байт')
Python system path (системные вызовы и файловая система в python)
Как избежать захода в определённые подкаталоги при os.walk?
Можно изменять список dirs на месте, удаляя элементы, в которые не нужно заходить. Например, dirs[:] = [d for d in dirs if d != 'skip'].
Вариант 3: os.mkdir для создания одного каталога
Как создать только один каталог, если родительская папка уже существует?
os.mkdir создает только конечный каталог, не создавая промежуточные. При отсутствии родителя возникает FileNotFoundError. Для единичных папок это может быть достаточно.
import os
try:
os.mkdir('new_folder')
except FileExistsError:
print('Папка уже существует')Python py file system (работа с файловой системой в python (os, shutil))
В чём отличие os.mkdir от os.makedirs?
os.mkdir создаёт только последний элемент пути, требуя существования всех вышестоящих. os.makedirs рекурсивно создаёт все недостающие промежуточные каталоги.
Вариант 4: shutil.copy и shutil.copytree для копирования
Как скопировать файл без метаданных или папку целиком?
shutil.copy копирует файл и устанавливает права доступа, но не сохраняет временные метки. shutil.copytree рекурсивно копирует всё дерево каталогов, используя по умолчанию shutil.copy2 для каждого файла.
import shutil
# Копирование файла с метаданными (права + время)
shutil.copy2('source.txt', 'dest.txt')
# Копирование только содержимого без метаданных
shutil.copy('source.txt', 'dest.txt')
# Копирование целого дерева
shutil.copytree('src_dir', 'dst_dir')аргументы программы python (аргументы командной строки программы на python)
Что произойдёт при копировании в существующую папку?
shutil.copytree требует, чтобы целевая директория не существовала, иначе возникает FileExistsError. Для обновления существующей используют shutil.copytree с параметром dirs_exist_ok=True (Python 3.8+).
Вариант 5: os.remove, os.rmdir и shutil.rmtree для удаления
Как удалить файл, пустую папку или всё дерево?
os.remove удаляет файл (не папку). os.rmdir удаляет только пустую папку. Для непустых папок используют shutil.rmtree, которая рекурсивно стирает всё содержимое.
import os, shutil
os.remove('file.txt')
os.rmdir('empty_dir')
shutil.rmtree('nonempty_dir')Python вызов программы (вызов программы из python)
Почему os.rmdir не удаляет непустую папку?
По соображениям безопасности: сначала нужно очистить папку вручную или использовать shutil.rmtree. Это предотвращает случайное удаление данных.
Вариант 6: os.rename и shutil.move для переименования и перемещения
Как переименовать или переместить файл/папку в то же или другое место?
os.rename работает только в пределах одной файловой системы. shutil.move может перемещать между разными дисками, копируя и удаляя оригинал. В большинстве случаев shutil.move надёжнее.
import os, shutil
# Переименование в той же папке
os.rename('old.txt', 'new.txt')
# Перемещение в другую папку
shutil.move('source.txt', '/destination/')Какие проблемы могут возникнуть при shutil.move на разных дисках?
Операция выполняется как копирование с последующим удалением, поэтому если копирование прервется, исходный файл может быть удален, а целевой создан не полностью. Для критичных данных рекомендуется сначала копировать, затем удалять.
Расширенные примеры применения os и shutil
1. Копирование с игнорированием определённых файлов
Функция shutil.copytree принимает аргумент ignore для фильтрации копируемых элементов. В примере исключаются файлы с расширением .tmp и папка __pycache__.
import shutil
def ignore_patterns(path, names):
ignored = set()
for name in names:
if name.endswith('.tmp') or name == '__pycache__':
ignored.add(name)
return ignored
shutil.copytree('source', 'dest', ignore=ignore_patterns, dirs_exist_ok=True)2. Поиск всех файлов определённого размера с помощью os.scandir
Рекурсивный обход с os.scandir для нахождения файлов больше заданного порога. Используется стек и DirEntry.stat() для получения размера.
import os
def find_large_files(root, min_size_mb=100):
min_size = min_size_mb * 1024 * 1024
stack = [root]
result = []
while stack:
dir_ = stack.pop()
try:
with os.scandir(dir_) as it:
for entry in it:
if entry.is_dir():
stack.append(entry.path)
elif entry.is_file() and entry.stat().st_size > min_size:
result.append((entry.path, entry.stat().st_size))
except PermissionError:
continue
return result
for path, size in find_large_files('/data', 500):
print(f'{path}: {size // (1024*1024)} MB')/data/video.mp4: 2048 MB /data/backup.zip: 1024 MB
3. Перемещение файлов с переименованием по шаблону
Используется shutil.move с формированием нового имени через os.path.splitext и текущую дату.
import os, shutil
from datetime import datetime
def archive_file(src, dst_dir):
base, ext = os.path.splitext(os.path.basename(src))
date = datetime.now().strftime('%Y%m%d_%H%M%S')
new_name = f'{base}_{date}{ext}'
dst = os.path.join(dst_dir, new_name)
shutil.move(src, dst)
return dst
moved = archive_file('report.xlsx', '/archive')
print(f'Перемещён в {moved}')Перемещён в /archive/report_20250321_154230.xlsx
4. Создание временной директории с помощью tempfile и shutil
Модуль tempfile в комбинации с shutil.rmtree позволяет безопасно создавать и удалять временные папки.
import tempfile
import shutil
import os
with tempfile.TemporaryDirectory() as tmpdir:
print(f'Временная папка: {tmpdir}')
# Создание файла внутри
with open(os.path.join(tmpdir, 'test.txt'), 'w') as f:
f.write('временные данные')
# Автоматическое удаление после выхода из контекста
print('Папка удалена')5. Получение и изменение прав доступа через os.stat и os.chmod
Используется os.stat для чтения прав и os.chmod для их изменения.
import os
import stat
path = 'script.py'
st = os.stat(path)
print(f'Текущие права: {oct(st.st_mode)}')
# Добавить право на выполнение для владельца
os.chmod(path, st.st_mode | stat.S_IXUSR)
print('Права обновлены')6. Рекурсивное удаление пустых папок с помощью os.walk
Проверяется, остались ли файлы в каталоге, и если нет – папка удаляется. Проход снизу вверх.
import os
for root, dirs, files in os.walk('/some/dir', topdown=False):
if not files and not dirs:
try:
os.rmdir(root)
print(f'Удалена пустая {root}')
except OSError:
pass7. Обработка ошибок при копировании с использованием try-except
При копировании на сетевой ресурс возможны временные сбои. Пример с повторными попытками.
import shutil
import time
src = 'data.csv'
dst = '/mnt/share/data.csv'
max_retries = 3
for attempt in range(max_retries):
try:
shutil.copy2(src, dst)
print('Копирование успешно')
break
except PermissionError as e:
print(f'Ошибка доступа: {e}')
time.sleep(1)
except FileNotFoundError:
print(f'Исходный файл {src} не найден')
break