shutil.md
1> **Источник:** https://python-all.ru/3.2/library/shutil.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 10.9. [`shutil`](https://python-all.ru/3.2/library/shutil.html#module-shutil) – высокоуровневые операции с файлами89**Исходный код:** [Lib/shutil.py](https://python-all.ru/src/3.2/Lib/shutil.py)1011---1213Модуль [`shutil`](https://python-all.ru/3.2/library/shutil.html#module-shutil) предоставляет ряд высокоуровневых операций над файлами и коллекциями файлов. В частности, предоставляются функции для копирования и удаления файлов. Для операций над отдельными файлами смотрите также модуль [`os`](https://python-all.ru/3.2/library/os.html#module-os).1415> **Предупреждение**16>17> Даже более высокоуровневые функции копирования файлов ([`shutil.copy()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy), [`shutil.copy2()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy2)) не могут скопировать все метаданные файла.18>19> На платформах POSIX это означает, что владелец и группа файла теряются, а также ACL. На Mac OS не используются ресурсные форки и другие метаданные. Это означает, что ресурсы будут потеряны, а коды типа и создателя файла будут некорректными. В Windows владельцы файлов, ACL и альтернативные потоки данных не копируются.2021## 10.9.1. Операции с каталогами и файлами2223#### `shutil.copyfileobj(fsrc, fdst[, length])`2425Копирует содержимое файлоподобного объекта *fsrc* в файлоподобный объект *fdst*. Целое число *length*, если задано, определяет размер буфера. В частности, отрицательное значение *length* означает копирование данных без разбиения исходных данных на части; по умолчанию данные читаются порциями, чтобы избежать неконтролируемого расхода памяти. Обратите внимание: если текущая позиция в файле объекта *fsrc* не равна 0, будут скопированы только данные от текущей позиции до конца файла.2627#### `shutil.copyfile(src, dst)`2829Копирует содержимое (без метаданных) файла с именем *src* в файл с именем *dst*. *dst* должно быть полным именем целевого файла; для копирования, принимающего путь к целевому каталогу, см. [`shutil.copy()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy). Если *src* и *dst* совпадают, возбуждается [`Error`](https://python-all.ru/3.2/library/shutil.html#shutil.Error). Целевое местоположение должно быть доступно для записи; в противном случае будет возбуждено исключение [`IOError`](https://python-all.ru/3.2/library/exceptions.html#IOError). Если *dst* уже существует, оно будет заменено. Специальные файлы, такие как символьные или блочные устройства и каналы, не могут быть скопированы этой функцией. *src* и *dst* – пути, заданные в виде строк.3031#### `shutil.copymode(src, dst)`3233Копирует биты разрешений из *src* в *dst*. Содержимое файла, владелец и группа не изменяются. *src* и *dst* – пути, заданные в виде строк.3435#### `shutil.copystat(src, dst)`3637Копирует биты разрешений, время последнего доступа, время последнего изменения и флаги из *src* в *dst*. Содержимое файла, владелец и группа не изменяются. *src* и *dst* – пути, заданные в виде строк.3839#### `shutil.copy(src, dst)`4041Копирует файл *src* в файл или каталог *dst*. Если *dst* – каталог, в указанном каталоге создаётся (или перезаписывается) файл с тем же базовым именем, что и *src*. Биты разрешений копируются. *src* и *dst* – пути, заданные в виде строк.4243#### `shutil.copy2(src, dst)`4445Аналогична [`shutil.copy()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy), но также копирует метаданные – фактически это просто [`shutil.copy()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy) с последующим вызовом [`copystat()`](https://python-all.ru/3.2/library/shutil.html#shutil.copystat). Это аналогично команде Unix **cp -p**.4647#### `shutil.ignore_patterns(*patterns)`4849Эта фабричная функция создаёт функцию, которую можно использовать в качестве вызываемого объекта для [`copytree()`](https://python-all.ru/3.2/library/shutil.html#shutil.copytree) аргумента *ignore*, игнорируя файлы и каталоги, соответствующие одному из предоставленных шаблонов в стиле glob *patterns*. Смотрите пример ниже.5051#### `shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)`5253Рекурсивно копирует всё дерево каталогов с корнем в *src*. Целевой каталог, заданный *dst*, не должен уже существовать; он будет создан, а также недостающие родительские каталоги. Права доступа и временны́е метки каталогов копируются с помощью [`copystat()`](https://python-all.ru/3.2/library/shutil.html#shutil.copystat), отдельные файлы копируются с помощью [`shutil.copy2()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy2).5455Если *symlinks* равен true, символические ссылки в исходном дереве представлены как символические ссылки в новом дереве, но метаданные исходных ссылок НЕ копируются; если false или не задано, содержимое и метаданные файлов, на которые указывают ссылки, копируются в новое дерево.5657Когда *symlinks* равен False, если файл, на который указывает симлинк, не существует, исключение будет добавлено в список ошибок, возбуждаемых в исключении [`Error`](https://python-all.ru/3.2/library/shutil.html#shutil.Error) в конце процесса копирования. Можно установить необязательный флаг *ignore\_dangling\_symlinks* в значение True, чтобы подавить это исключение. Обратите внимание, что эта опция не действует на платформах, не поддерживающих [`os.symlink()`](https://python-all.ru/3.2/library/os.html#os.symlink).5859Если задан *ignore*, он должен быть вызываемым объектом, который будет получать в качестве аргументов каталог, посещаемый функцией [`copytree()`](https://python-all.ru/3.2/library/shutil.html#shutil.copytree), и список его содержимого, возвращаемый функцией [`os.listdir()`](https://python-all.ru/3.2/library/os.html#os.listdir). Поскольку [`copytree()`](https://python-all.ru/3.2/library/shutil.html#shutil.copytree) вызывается рекурсивно, вызываемый объект *ignore* будет вызываться один раз для каждого копируемого каталога. Вызываемый объект должен возвращать последовательность имён каталогов и файлов относительно текущего каталога (т.е. подмножество элементов своего второго аргумента); эти имена затем будут игнорироваться в процессе копирования. [`ignore_patterns()`](https://python-all.ru/3.2/library/shutil.html#shutil.ignore_patterns) можно использовать для создания такого вызываемого объекта, который игнорирует имена на основе шаблонов в стиле glob.6061Если возникнут исключения, возбуждается исключение [`Error`](https://python-all.ru/3.2/library/shutil.html#shutil.Error) со списком причин.6263Если указан *copy\_function*, это должен быть вызываемый объект, который будет использоваться для копирования каждого файла. Он будет вызван с исходным путём и целевым путём в качестве аргументов. По умолчанию используется [`shutil.copy2()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy2), но можно использовать любую функцию с такой же сигнатурой (например, [`copy()`](https://python-all.ru/3.2/library/copy.html#module-copy)).6465Изменено в версии 3.2: Добавлен аргумент *copy\_function*, позволяющий указать собственную функцию копирования.6667Изменено в версии 3.2: Добавлен аргумент *ignore\_dangling\_symlinks* для подавления ошибок оборванных символических ссылок, когда *symlinks* равен false.6869#### `shutil.rmtree(path, ignore_errors=False, onerror=None)`7071Удаляет целое дерево каталогов; *path* должен указывать на каталог (но не на символическую ссылку на каталог). Если *ignore\_errors* равен true, ошибки, возникающие при неудачном удалении, игнорируются; если false или не указан, такие ошибки обрабатываются вызовом обработчика, заданного *onerror*, или, если он не указан, вызывается исключение.7273Если указан *onerror*, это должен быть вызываемый объект, принимающий три параметра: *function*, *path* и *excinfo*. Первый параметр, *function*, – это функция, возбудившая исключение; это может быть [`os.path.islink()`](https://python-all.ru/3.2/library/os.path.html#os.path.islink), [`os.listdir()`](https://python-all.ru/3.2/library/os.html#os.listdir), [`os.remove()`](https://python-all.ru/3.2/library/os.html#os.remove) или [`os.rmdir()`](https://python-all.ru/3.2/library/os.html#os.rmdir). Второй параметр, *path*, – это имя пути, переданное *function*. Третий параметр, *excinfo*, – это информация об исключении, возвращаемая [`sys.exc_info()`](https://python-all.ru/3.2/library/sys.html#sys.exc_info). Исключения, возбуждённые *onerror*, не перехватываются.7475#### `shutil.move(src, dst)`7677Рекурсивно перемещает файл или каталог (*src*) в другое место (*dst*).7879Если назначение является каталогом или симлинком на каталог, то *src* перемещается внутрь этого каталога.8081Целевой каталог не должен уже существовать. Если целевой путь уже существует, но не является каталогом, он может быть перезаписан в зависимости от семантики [`os.rename()`](https://python-all.ru/3.2/library/os.html#os.rename).8283Если целевой объект находится в той же файловой системе, используется [`os.rename()`](https://python-all.ru/3.2/library/os.html#os.rename). В противном случае *src* копируется (с помощью [`shutil.copy2()`](https://python-all.ru/3.2/library/shutil.html#shutil.copy2)) в *dst*, а затем удаляется.8485#### `exception shutil.Error`8687Это исключение собирает исключения, возбуждённые во время операции с несколькими файлами. Для [`copytree()`](https://python-all.ru/3.2/library/shutil.html#shutil.copytree) аргумент исключения представляет собой список трёхэлементных кортежей (*srcname*, *dstname*, *исключение*).8889### 10.9.1.1. Пример copytree9091Этот пример является реализацией функции [`copytree()`](https://python-all.ru/3.2/library/shutil.html#shutil.copytree), описанной выше, с опущенной строкой документации. Он демонстрирует многие другие функции, предоставляемые этим модулем.9293```python94def copytree(src, dst, symlinks=False):95 names = os.listdir(src)96 os.makedirs(dst)97 errors = []98 for name in names:99 srcname = os.path.join(src, name)100 dstname = os.path.join(dst, name)101 try:102 if symlinks and os.path.islink(srcname):103 linkto = os.readlink(srcname)104 os.symlink(linkto, dstname)105 elif os.path.isdir(srcname):106 copytree(srcname, dstname, symlinks)107 else:108 copy2(srcname, dstname)109 # XXX Что насчет устройств, сокетов и т.д.?110 except (IOError, os.error) as why:111 errors.append((srcname, dstname, str(why)))112 # перехватываем ошибку от рекурсивного copytree, чтобы мы могли113 # продолжить с другими файлами114 except Error as err:115 errors.extend(err.args[0])116 try:117 copystat(src, dst)118 except WindowsError:119 # не удается скопировать время доступа к файлам в Windows120 pass121 except OSError as why:122 errors.extend((src, dst, str(why)))123 if errors:124 raise Error(errors)125```126127Другой пример, использующий вспомогательную функцию [`ignore_patterns()`](https://python-all.ru/3.2/library/shutil.html#shutil.ignore_patterns):128129```python130from shutil import copytree, ignore_patterns131132copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))133```134135Это скопирует все, кроме файлов `.pyc` и файлов или каталогов, имя которых начинается с `tmp`.136137Ещё один пример, использующий аргумент *ignore* для добавления вызова журналирования:138139```python140from shutil import copytree141import logging142143def _logpath(path, names):144 logging.info('Working in %s' % path)145 return [] # ничего не будет проигнорировано146147copytree(source, destination, ignore=_logpath)148```149150## 10.9.2. Операции архивирования151152Также предоставляются высокоуровневые утилиты для создания и чтения сжатых и архивных файлов. Они полагаются на модули [`zipfile`](https://python-all.ru/3.2/library/zipfile.html#module-zipfile) и [`tarfile`](https://python-all.ru/3.2/library/tarfile.html#module-tarfile).153154#### `shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])`155156Создаёт архивный файл (например, zip или tar) и возвращает его имя.157158*base\_name* – это имя создаваемого файла, включая путь, без расширения, специфичного для формата. *format* – это формат архива: один из «zip», «tar», «bztar» (если доступен модуль [`bz2`](https://python-all.ru/3.2/library/bz2.html#module-bz2)) или «gztar».159160*root\_dir* – это каталог, который будет корневым каталогом архива; например, мы обычно переходим в *root\_dir* перед созданием архива.161162*base\_dir* – это каталог, из которого начинается архивирование; т.е. *base\_dir* будет общим префиксом всех файлов и каталогов в архиве.163164*root\_dir* и *base\_dir* по умолчанию равны текущему каталогу.165166*owner* и *group* используются при создании tar-архива. По умолчанию используются текущий владелец и группа.167168*logger* должен быть объектом, совместимым с [**PEP 282**](https://python-all.ru/3.2/library/shutil.html), обычно экземпляром [`logging.Logger`](https://python-all.ru/3.2/library/logging.html#logging.Logger).169170Новое в версии 3.2.171172#### `shutil.get_archive_formats()`173174Возвращает список поддерживаемых форматов архивирования. Каждый элемент возвращаемой последовательности – кортеж `(name, description)`175176По умолчанию [`shutil`](https://python-all.ru/3.2/library/shutil.html#module-shutil) предоставляет следующие форматы:177178- *gztar*: tar-файл, сжатый gzip179- *bztar*: tar-файл, сжатый bzip2 (если доступен модуль [`bz2`](https://python-all.ru/3.2/library/bz2.html#module-bz2)).180- *tar*: несжатый tar-файл181- *zip*: ZIP-файл182183Можно зарегистрировать новые форматы или предоставить собственный архиватор для любых существующих форматов, используя [`register_archive_format()`](https://python-all.ru/3.2/library/shutil.html#shutil.register_archive_format).184185Новое в версии 3.2.186187#### `shutil.register_archive_format(name, function[, extra_args[, description]])`188189Регистрирует архиватор для формата *name*. *function* – это вызываемый объект, который будет использоваться для вызова архиватора.190191Если задано, *extra\_args* – это последовательность пар `(name, value)`, которые будут использоваться как дополнительные именованные аргументы при вызове архиватора.192193*description* используется функцией [`get_archive_formats()`](https://python-all.ru/3.2/library/shutil.html#shutil.get_archive_formats), которая возвращает список архиваторов. По умолчанию – пустой список.194195Новое в версии 3.2.196197#### `shutil.unregister_archive_format(name)`198199Удалите имя формата архива *name* из списка поддерживаемых форматов.200201Новое в версии 3.2.202203#### `shutil.unpack_archive(filename[, extract_dir[, format]])`204205Распаковывает архив. *filename* – это полный путь к архиву.206207*extract\_dir* – имя целевой директории, в которую распаковывается архив. Если не указано, используется текущая рабочая директория.208209*format* – это формат архива: один из «zip», «tar» или «gztar». Или любой другой формат, зарегистрированный с помощью [`register_unpack_format()`](https://python-all.ru/3.2/library/shutil.html#shutil.register_unpack_format). Если не указан, [`unpack_archive()`](https://python-all.ru/3.2/library/shutil.html#shutil.unpack_archive) использует расширение имени файла архива и проверяет, зарегистрирован ли распаковщик для этого расширения. Если ни один не найден, возбуждается [`ValueError`](https://python-all.ru/3.2/library/exceptions.html#ValueError).210211Новое в версии 3.2.212213#### `shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])`214215Регистрирует формат распаковки. *name* – это имя формата, а *extensions* – список расширений, соответствующих формату, например `.zip` для Zip-файлов.216217*function* – это вызываемый объект, который будет использоваться для распаковки архивов. Вызываемый объект будет получать путь к архиву, за которым следует каталог, в который необходимо извлечь архив.218219Если указано, *extra\_args* – это последовательность кортежей `(name, value)`, которые будут переданы как именованные аргументы вызываемому объекту.220221*description* может быть указан для описания формата и будет возвращён функцией [`get_unpack_formats()`](https://python-all.ru/3.2/library/shutil.html#shutil.get_unpack_formats).222223Новое в версии 3.2.224225#### `shutil.unregister_unpack_format(name)`226227Отменяет регистрацию формата распаковки. *name* – имя формата.228229Новое в версии 3.2.230231#### `shutil.get_unpack_formats()`232233Возвращает список всех зарегистрированных форматов распаковки. Каждый элемент возвращаемой последовательности – это кортеж `(name, extensions, description)`.234235По умолчанию [`shutil`](https://python-all.ru/3.2/library/shutil.html#module-shutil) предоставляет следующие форматы:236237- *gztar*: tar-файл, сжатый gzip238- *bztar*: tar-файл, сжатый bzip2 (если доступен модуль [`bz2`](https://python-all.ru/3.2/library/bz2.html#module-bz2)).239- *tar*: несжатый tar-файл240- *zip*: ZIP-файл241242Можно зарегистрировать новые форматы или предоставить собственный распаковщик для любых существующих форматов, используя [`register_unpack_format()`](https://python-all.ru/3.2/library/shutil.html#shutil.register_unpack_format).243244Новое в версии 3.2.245246### 10.9.2.1. Пример архивирования247248В этом примере создаётся tar-архив, сжатый gzip, содержащий все файлы, найденные в каталоге пользователя `.ssh`:249250```python251>>> from shutil import make_archive252>>> import os253>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))254>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))255>>> make_archive(archive_name, 'gztar', root_dir)256'/Users/tarek/myarchive.tar.gz'257```258259Полученный архив содержит:260261```python262$ tar -tzvf /Users/tarek/myarchive.tar.gz263drwx------ tarek/staff 0 2010-02-01 16:23:40 ./264-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys265-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config266-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa267-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub268-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa269-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub270-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts271```272