shutil.md
1> **Источник:** https://python-all.ru/2.7/library/shutil.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 10.10. [`shutil`](https://python-all.ru/2.7/library/shutil.html#module-shutil) – высокоуровневые операции с файлами89**Исходный код:** [Lib/shutil.py](https://python-all.ru/src/2.7/Lib/shutil.py)1011---1213Модуль [`shutil`](https://python-all.ru/2.7/library/shutil.html#module-shutil) предоставляет ряд высокоуровневых операций с файлами и наборами файлов. В частности, предоставлены функции, которые поддерживают копирование и удаление файлов. Для операций с отдельными файлами см. также модуль [`os`](https://python-all.ru/2.7/library/os.html#module-os).1415> **Предупреждение**16>17> Даже функции копирования файлов более высокого уровня ([`shutil.copy()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy), [`shutil.copy2()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy2)) не могут скопировать все метаданные файла.18>19> На платформах POSIX это означает, что владелец и группа файла теряются, а также ACL. На Mac OS не используются ресурсные форки и другие метаданные. Это означает, что ресурсы будут потеряны, а коды типа и создателя файла будут некорректными. В Windows владельцы файлов, ACL и альтернативные потоки данных не копируются.2021## 10.10.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/2.7/library/shutil.html#shutil.copy) для копирования, принимающего целевой каталог. Если *src* и *dst* – один и тот же файл, возбуждается [`Error`](https://python-all.ru/2.7/library/shutil.html#shutil.Error). Целевое расположение должно быть доступно для записи; в противном случае будет возбуждено исключение [`IOError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.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Идентично [`copy()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy), за исключением того, что [`copy2()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy2) также пытается сохранить метаданные файла.4647[`copy2()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy2) использует [`copystat()`](https://python-all.ru/2.7/library/shutil.html#shutil.copystat) для копирования метаданных файла. Подробнее см. [`copystat()`](https://python-all.ru/2.7/library/shutil.html#shutil.copystat).4849#### `shutil.ignore_patterns(*patterns)`5051Эта фабричная функция создаёт функцию, которую можно использовать как вызываемый объект для аргумента *ignore* функции [`copytree()`](https://python-all.ru/2.7/library/shutil.html#shutil.copytree), игнорируя файлы и каталоги, соответствующие одному из предоставленных *шаблонов* в стиле glob. См. пример ниже.5253Новое в версии 2.6.5455#### `shutil.copytree(src, dst, symlinks=False, ignore=None)`5657Рекурсивно копирует всё дерево каталогов с корнем в *src*. Целевой каталог с именем *dst* не должен существовать; он будет создан вместе с отсутствующими родительскими каталогами. Права доступа и временные метки каталогов копируются с помощью [`copystat()`](https://python-all.ru/2.7/library/shutil.html#shutil.copystat), отдельные файлы копируются с помощью [`shutil.copy2()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy2).5859Если *symlinks* равен true, символические ссылки в исходном дереве представлены как символические ссылки в новом дереве, но метаданные исходных ссылок НЕ копируются; если false или не задано, содержимое и метаданные файлов, на которые указывают ссылки, копируются в новое дерево.6061Если задан *ignore*, это должен быть вызываемый объект, который будет получать в качестве аргументов каталог, обрабатываемый [`copytree()`](https://python-all.ru/2.7/library/shutil.html#shutil.copytree), и список его содержимого, возвращённый [`os.listdir()`](https://python-all.ru/2.7/library/os.html#os.listdir). Поскольку [`copytree()`](https://python-all.ru/2.7/library/shutil.html#shutil.copytree) вызывается рекурсивно, вызываемый объект *ignore* будет вызываться один раз для каждого копируемого каталога. Вызываемый объект должен возвращать последовательность имён каталогов и файлов относительно текущего каталога (т.е. подмножество элементов из его второго аргумента); эти имена будут игнорироваться в процессе копирования. [`ignore_patterns()`](https://python-all.ru/2.7/library/shutil.html#shutil.ignore_patterns) можно использовать для создания такого вызываемого объекта, который игнорирует имена на основе шаблонов в стиле glob.6263Если возникают исключения, вызывается [`Error`](https://python-all.ru/2.7/library/shutil.html#shutil.Error) со списком причин.6465Данный исходный код следует рассматривать скорее как пример, а не как универсальный инструмент.6667Изменено в версии 2.3: [`Error`](https://python-all.ru/2.7/library/shutil.html#shutil.Error) возбуждается, если при копировании возникают исключения, вместо вывода сообщения.6869Изменено в версии 2.5: Создаёт промежуточные каталоги, необходимые для создания *dst*, вместо возбуждения ошибки. Копирует права доступа и временные метки каталогов с помощью [`copystat()`](https://python-all.ru/2.7/library/shutil.html#shutil.copystat).7071Изменено в версии 2.6: Добавлен аргумент *ignore* для возможности влиять на то, что копируется.7273#### `shutil.rmtree(path[, ignore_errors[, onerror]])`7475Удаляет целое дерево каталогов; *path* должен указывать на каталог (но не на символическую ссылку на каталог). Если *ignore\_errors* равен true, ошибки, возникающие при неудачном удалении, игнорируются; если false или не указан, такие ошибки обрабатываются вызовом обработчика, заданного *onerror*, или, если он не указан, вызывается исключение.7677Если *onerror* указан, он должен быть вызываемым объектом, принимающим три параметра: *function*, *path* и *excinfo*. Первый параметр, *function*, – это функция, возбудившая исключение; это будет [`os.path.islink()`](https://python-all.ru/2.7/library/os.path.html#os.path.islink), [`os.listdir()`](https://python-all.ru/2.7/library/os.html#os.listdir), [`os.remove()`](https://python-all.ru/2.7/library/os.html#os.remove) или [`os.rmdir()`](https://python-all.ru/2.7/library/os.html#os.rmdir). Второй параметр, *path*, – это имя пути, переданное функции *function*. Третий параметр, *excinfo*, – это информация об исключении, возвращаемая [`sys.exc_info()`](https://python-all.ru/2.7/library/sys.html#sys.exc_info). Исключения, возбуждённые *onerror*, не перехватываются.7879Изменено в версии 2.6: Явно проверяет, является ли *path* символической ссылкой, и возбуждает [`OSError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.OSError) в этом случае.8081#### `shutil.move(src, dst)`8283Рекурсивно перемещает файл или каталог (*src*) в другое место (*dst*).8485Если назначение – существующий каталог, то *src* перемещается внутрь этого каталога. Если назначение уже существует, но не является каталогом, оно может быть перезаписано в зависимости от семантики [`os.rename()`](https://python-all.ru/2.7/library/os.html#os.rename).8687Если целевой объект находится в текущей файловой системе, то используется [`os.rename()`](https://python-all.ru/2.7/library/os.html#os.rename). В противном случае *src* копируется (с помощью [`shutil.copy2()`](https://python-all.ru/2.7/library/shutil.html#shutil.copy2)) в *dst*, а затем удаляется.8889Новое в версии 2.3.9091#### `exception shutil.Error`9293Это исключение собирает исключения, возникающие во время операции с несколькими файлами. Для [`copytree()`](https://python-all.ru/2.7/library/shutil.html#shutil.copytree) аргумент исключения представляет собой список кортежей из трёх элементов (*srcname*, *dstname*, *исключение*).9495Новое в версии 2.3.9697### 10.10.1.1. пример copytree9899Этот пример представляет собой реализацию функции [`copytree()`](https://python-all.ru/2.7/library/shutil.html#shutil.copytree), описанной выше, с опущенной строкой документации. Он демонстрирует многие другие функции, предоставляемые этим модулем.100101```python102def copytree(src, dst, symlinks=False, ignore=None):103 names = os.listdir(src)104 if ignore is not None:105 ignored_names = ignore(src, names)106 else:107 ignored_names = set()108109 os.makedirs(dst)110 errors = []111 for name in names:112 if name in ignored_names:113 continue114 srcname = os.path.join(src, name)115 dstname = os.path.join(dst, name)116 try:117 if symlinks and os.path.islink(srcname):118 linkto = os.readlink(srcname)119 os.symlink(linkto, dstname)120 elif os.path.isdir(srcname):121 copytree(srcname, dstname, symlinks, ignore)122 else:123 copy2(srcname, dstname)124 # XXX Что насчет устройств, сокетов и т.д.?125 except (IOError, os.error) as why:126 errors.append((srcname, dstname, str(why)))127 # перехватываем ошибку от рекурсивного copytree, чтобы мы могли128 # продолжить с другими файлами129 except Error as err:130 errors.extend(err.args[0])131 try:132 copystat(src, dst)133 except WindowsError:134 # не удается скопировать время доступа к файлам в Windows135 pass136 except OSError as why:137 errors.extend((src, dst, str(why)))138 if errors:139 raise Error(errors)140```141142Ещё один пример, использующий вспомогательную функцию [`ignore_patterns()`](https://python-all.ru/2.7/library/shutil.html#shutil.ignore_patterns):143144```python145from shutil import copytree, ignore_patterns146147copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))148```149150При этом будет скопировано всё, кроме файлов `.pyc` и файлов или каталогов, имена которых начинаются с `tmp`.151152Ещё один пример, использующий аргумент *ignore* для добавления вызова журналирования:153154```python155from shutil import copytree156import logging157158def _logpath(path, names):159 logging.info('Working in %s' % path)160 return [] # ничего не будет проигнорировано161162copytree(source, destination, ignore=_logpath)163```164165## 10.10.2. Операции архивирования166167Также предоставляются высокоуровневые утилиты для создания и чтения сжатых и архивных файлов. Они основаны на модулях [`zipfile`](https://python-all.ru/2.7/library/zipfile.html#module-zipfile) и [`tarfile`](https://python-all.ru/2.7/library/tarfile.html#module-tarfile).168169#### `shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])`170171Создаёт архивный файл (например, zip или tar) и возвращает его имя.172173*base\_name* – это имя создаваемого файла, включая путь, без расширения, специфичного для формата. *format* – это формат архива: один из «zip» (если доступен модуль [`zlib`](https://python-all.ru/2.7/library/zlib.html#module-zlib) или внешняя программа `zip`), «tar», «gztar» (если доступен модуль [`zlib`](https://python-all.ru/2.7/library/zlib.html#module-zlib)), или «bztar» (если доступен модуль [`bz2`](https://python-all.ru/2.7/library/bz2.html#module-bz2)).174175*root\_dir* – это каталог, который будет корневым каталогом архива; т.е. мы обычно переходим в *root\_dir* перед созданием архива.176177*base\_dir* – это каталог, с которого начинается архивация; т.е. *base\_dir* будет общим префиксом для всех файлов и каталогов в архиве.178179*root\_dir* и *base\_dir* по умолчанию равны текущему каталогу.180181*owner* и *group* используются при создании tar-архива. По умолчанию используются текущий владелец и группа.182183*logger* должен быть объектом, совместимым с [**PEP 282**](https://python-all.ru/2.7/library/shutil.html), обычно экземпляром [`logging.Logger`](https://python-all.ru/2.7/library/logging.html#logging.Logger).184185Новое в версии 2.7.186187#### `shutil.get_archive_formats()`188189Возвращает список поддерживаемых форматов архивации. Каждый элемент возвращаемой последовательности – это кортеж `(name, description)`.190191По умолчанию [`shutil`](https://python-all.ru/2.7/library/shutil.html#module-shutil) предоставляет следующие форматы:192193- *zip*: ZIP-файл (если доступен модуль [`zlib`](https://python-all.ru/2.7/library/zlib.html#module-zlib) или внешняя программа `zip`).194- *tar*: несжатый tar-файл.195- *gztar*: tar-файл, сжатый gzip (если доступен модуль [`zlib`](https://python-all.ru/2.7/library/zlib.html#module-zlib)).196- *bztar*: tar-файл, сжатый bzip2 (если доступен модуль [`bz2`](https://python-all.ru/2.7/library/bz2.html#module-bz2)).197198Можно зарегистрировать новые форматы или предоставить собственный архиватор для любого существующего формата, используя [`register_archive_format()`](https://python-all.ru/2.7/library/shutil.html#shutil.register_archive_format).199200Новое в версии 2.7.201202#### `shutil.register_archive_format(name, function[, extra_args[, description]])`203204Регистрирует архиватор для формата *name*. *function* – это вызываемый объект, который будет использоваться для вызова архиватора.205206Если указан, *extra\_args* – это последовательность `(name, value)`, которая будет использоваться как дополнительные ключевые аргументы при использовании вызываемого архиватора.207208*description* используется [`get_archive_formats()`](https://python-all.ru/2.7/library/shutil.html#shutil.get_archive_formats), которая возвращает список архиваторов. По умолчанию – пустой список.209210Новое в версии 2.7.211212#### `shutil.unregister_archive_format(name)`213214Удалите имя формата архива *name* из списка поддерживаемых форматов.215216Новое в версии 2.7.217218### 10.10.2.1. Пример архивирования219220В этом примере мы создаём tar-архив, сжатый gzip, содержащий все файлы, найденные в каталоге `.ssh` пользователя:221222```python223>>> from shutil import make_archive224>>> import os225>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))226>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))227>>> make_archive(archive_name, 'gztar', root_dir)228'/Users/tarek/myarchive.tar.gz'229```230231Полученный архив содержит:232233```console234$ tar -tzvf /Users/tarek/myarchive.tar.gz235drwx------ tarek/staff 0 2010-02-01 16:23:40 ./236-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys237-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config238-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa239-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub240-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa241-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub242-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts243```244