Python shutil.copytree: скопировать папку с файлами
shutil.copytree() рекурсивно копирует каталог вместе с вложенными файлами и возвращает путь назначения. По умолчанию целевая папка не должна существовать: при наличии выбрасывается FileExistsError. Параметр dirs_exist_ok=True (Python 3.8+) разрешает слияние с существующим каталогом.
Скопировать папку и исключить кэш
import shutil
from pathlib import Path
src = Path("src")
dst = Path("backup")
src.mkdir(exist_ok=True)
(src / "app.py").write_text("print('ok')\n", encoding="utf-8")
shutil.copytree(
src,
dst,
ignore=shutil.ignore_patterns("*.pyc", "__pycache__"),
)
print((dst / "app.py").read_text(encoding="utf-8").strip()) # print('ok')ignore_patterns создаёт функцию для аргумента ignore; она получает каталог и список имён и возвращает то, что нужно пропустить. Шаблоны проверяются по именам, а не по полным путям. Для более сложной фильтрации напишите свою функцию и передайте её в ignore.
copytree по умолчанию использует copy2, поэтому сохраняет время изменения и права доступа. Символические ссылки по умолчанию разыменовываются; symlinks=True копирует саму ссылку. Жёсткие ссылки не сохраняются: каждый файл получает отдельную копию. Для больших деревьев это может удвоить место.
Слить с существующим каталогом
import shutil
shutil.copytree("src", "backup", dirs_exist_ok=True)
print("слияние завершено") # слияние завершеноdirs_exist_ok=True не удаляет лишние файлы в приёмнике: он перезаписывает совпавшие и добавляет новые. Если нужна точная копия без старых файлов, сначала удалите каталог или используйте dirsync из сторонней библиотеки. Будьте осторожны с правами: при слиянии файлы приёмника могут остаться от предыдущей версии.
Функция работает только с локальной файловой системой и не подходит для сетевых URL, S3 или архивов. Для копирования по сети используйте rsync, для облака — SDK провайдера. При копировании в цикле проверяйте свободное место и обрабатывайте OSError: частично скопированное дерево останется на диске.
Документация: shutil.copytree, shutil.ignore_patterns.