Содержание страницы
11.10. shutil – Высокоуровневые операции с файлами¶shutil – High-level file operations
Исходный код: Lib/shutil.py
Модуль shutil предоставляет ряд высокоуровневых операций над файлами и коллекциями файлов. В частности, предоставляются функции для копирования и удаления файлов. Для операций над отдельными файлами смотрите также модуль os.
Предупреждение
Даже более высокоуровневые функции копирования файлов (shutil.copy(), shutil.copy2()) не могут скопировать все метаданные файла.
На платформах POSIX это означает, что владелец и группа файла теряются, а также ACL. На Mac OS не используются ресурсные форки и другие метаданные. Это означает, что ресурсы будут потеряны, а коды типа и создателя файла будут некорректными. В Windows владельцы файлов, ACL и альтернативные потоки данных не копируются.
11.10.1. Операции с каталогами и файлами¶Directory and files operations
- shutil.copyfileobj(fsrc, fdst[, length])¶
Копирует содержимое файлоподобного объекта fsrc в файлоподобный объект fdst. Целое число length, если задано, определяет размер буфера. В частности, отрицательное значение length означает копирование данных без разбиения исходных данных на части; по умолчанию данные читаются порциями, чтобы избежать неконтролируемого расхода памяти. Обратите внимание: если текущая позиция в файле объекта fsrc не равна 0, будут скопированы только данные от текущей позиции до конца файла.
- shutil.copyfile(src, dst, *, follow_symlinks=True)¶
Копирует содержимое (без метаданных) файла с именем src в файл с именем dst и возвращает dst. src и dst – это пути, заданные строками. dst должен быть полным именем целевого файла; обратитесь к shutil.copy() для версии, которая принимает путь к целевой директории. Если src и dst указывают на один и тот же файл, возбуждается SameFileError.
Целевой каталог должен быть доступен для записи; в противном случае будет возбуждено исключение OSError. Если dst уже существует, он будет заменён. Специальные файлы, такие как символьные или блочные устройства и каналы, не могут быть скопированы этой функцией.
Если follow_symlinks имеет значение false и src является символической ссылкой, будет создана новая символическая ссылка вместо копирования файла, на который указывает src.
Изменено в версии 3.3: Раньше возбуждалось IOError вместо OSError. Добавлен аргумент follow_symlinks. Теперь возвращает dst.
Изменено в версии 3.4: Возбуждается SameFileError вместо Error. Поскольку первое является подклассом второго, это изменение обратно совместимо.
- exception shutil.SameFileError¶
Это исключение возбуждается, если источник и назначение в copyfile() являются одним и тем же файлом.
Новое в версии 3.4.
- shutil.copymode(src, dst, *, follow_symlinks=True)¶
Копирует биты прав доступа из src в dst. Содержимое файла, владелец и группа не изменяются. src и dst – это пути, заданные строками. Если follow_symlinks равно false и оба src и dst являются символическими ссылками, copymode() попытается изменить режим самой dst (а не файла, на который она указывает). Эта функциональность доступна не на всех платформах; пожалуйста, обратитесь к copystat() для получения дополнительной информации. Если copymode() не может модифицировать символические ссылки на данной платформе, и её просят это сделать, она ничего не делает и возвращается.
Изменено в версии 3.3: Добавлен аргумент follow_symlinks.
- shutil.copystat(src, dst, *, follow_symlinks=True)¶
Копирует биты прав доступа, время последнего доступа, время последнего изменения и флаги из src в dst. На Linux copystat() также копирует «расширенные атрибуты», если это возможно. Содержимое файла, владелец и группа не изменяются. src и dst – это пути, заданные строками.
Если follow_symlinks равно false и src и dst обе являются символическими ссылками, copystat() будет работать с самими символическими ссылками, а не с файлами, на которые они указывают – читая информацию из символической ссылки src и записывая информацию в символическую ссылку dst.
Примечание
Не все платформы предоставляют возможность просматривать и изменять символические ссылки. Python сам может сообщить, какая функциональность доступна локально.
- Если os.chmod in os.supports_follow_symlinks равно True, copystat() может изменять биты прав доступа символической ссылки.
- Если os.utime in os.supports_follow_symlinks равно True, copystat() может изменять время последнего доступа и время последнего изменения символической ссылки.
- Если os.chflags in os.supports_follow_symlinks равно True, copystat() может изменять флаги символической ссылки. (os.chflags доступна не на всех платформах.)
На платформах, где часть или вся эта функциональность недоступна, при запросе на модификацию символической ссылки copystat() скопирует всё, что сможет. copystat() никогда не возвращает ошибку.
Пожалуйста, обратитесь к os.supports_follow_symlinks для получения дополнительной информации.
Изменено в версии 3.3: Добавлен аргумент follow_symlinks и поддержка расширенных атрибутов Linux.
- shutil.copy(src, dst, *, follow_symlinks=True)¶
Копирует файл src в файл или каталог dst. src и dst должны быть строками. Если dst указывает на каталог, файл будет скопирован в dst с использованием базового имени из src. Возвращает путь к только что созданному файлу.
Если follow_symlinks имеет значение false и src является символической ссылкой, dst будет создан как символическая ссылка. Если follow_symlinks имеет значение true и src является символической ссылкой, dst будет копией файла, на который указывает src.
copy() копирует данные файла и режим прав доступа к файлу (см. os.chmod()). Другие метаданные, такие как время создания и модификации файла, не сохраняются. Чтобы сохранить все метаданные из оригинала, используйте вместо этого copy2().
Изменено в версии 3.3: Добавлен аргумент follow_symlinks. Теперь возвращает путь к созданному файлу.
- shutil.copy2(src, dst, *, follow_symlinks=True)¶
Идентична copy(), за исключением того, что copy2() также пытается сохранить все метаданные файла.
Когда follow_symlinks равно false и src является символической ссылкой, copy2() пытается скопировать все метаданные из символической ссылки src в только что созданную символическую ссылку dst. Однако эта функциональность доступна не на всех платформах. На платформах, где часть или вся эта функциональность недоступна, copy2() сохранит все метаданные, которые сможет; copy2() никогда не возвращает ошибку.
copy2() использует copystat() для копирования метаданных файла. Пожалуйста, обратитесь к copystat() для получения дополнительной информации о поддержке платформой модификации метаданных символической ссылки.
Изменено в версии 3.3: Добавлен аргумент follow_symlinks, также предпринята попытка копировать расширенные атрибуты файловой системы (пока только Linux). Теперь возвращает путь к созданному файлу.
- shutil.ignore_patterns(*patterns)¶
Эта фабричная функция создаёт функцию, которую можно использовать в качестве вызываемого объекта для copytree() аргумента ignore, игнорируя файлы и каталоги, соответствующие одному из предоставленных шаблонов в стиле glob patterns. Смотрите пример ниже.
- shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)¶
Рекурсивно копирует всё дерево каталогов с корнем в src, возвращая целевой каталог. Целевой каталог, заданный dst, не должен уже существовать; он будет создан вместе с отсутствующими родительскими каталогами. Права доступа и временные метки каталогов копируются с помощью copystat(), отдельные файлы копируются с помощью shutil.copy2().
Если symlinks имеет значение true, символические ссылки в исходном дереве представляются как символические ссылки в новом дереве, и метаданные исходных ссылок будут скопированы насколько это позволяет платформа; если false или аргумент опущен, содержимое и метаданные файлов, на которые указывают ссылки, копируются в новое дерево.
Когда symlinks равно false, если файл, на который указывает символьная ссылка, не существует, в конец процесса копирования в список ошибок будет добавлено исключение, которое будет возбуждено как Error. Можно установить необязательный флаг ignore_dangling_symlinks в true, чтобы подавить это исключение. Обратите внимание, что эта опция не влияет на платформы, не поддерживающие os.symlink().
Если задан ignore, он должен быть вызываемым объектом, который будет получать в качестве аргументов каталог, посещаемый функцией copytree(), и список его содержимого, возвращаемый функцией os.listdir(). Поскольку copytree() вызывается рекурсивно, вызываемый объект ignore будет вызываться один раз для каждого копируемого каталога. Вызываемый объект должен возвращать последовательность имён каталогов и файлов относительно текущего каталога (т.е. подмножество элементов своего второго аргумента); эти имена затем будут игнорироваться в процессе копирования. ignore_patterns() можно использовать для создания такого вызываемого объекта, который игнорирует имена на основе шаблонов в стиле glob.
Если возникнут исключения, возбуждается исключение Error со списком причин.
Если задан copy_function, он должен быть вызываемым объектом, который будет использоваться для копирования каждого файла. Он будет вызван с исходным и целевым путями в качестве аргументов. По умолчанию используется shutil.copy2(), но может использоваться любая функция, поддерживающая ту же сигнатуру (например, shutil.copy()).
Изменено в версии 3.3: Копирует метаданные, когда symlinks имеет значение false. Теперь возвращает dst.
Изменено в версии 3.2: Добавлен аргумент copy_function, позволяющий указать собственную функцию копирования. Добавлен аргумент ignore_dangling_symlinks для подавления ошибок оборванных символических ссылок, когда symlinks имеет значение false.
- shutil.rmtree(path, ignore_errors=False, onerror=None)¶
Удаляет целое дерево каталогов; path должен указывать на каталог (но не на символическую ссылку на каталог). Если ignore_errors равен true, ошибки, возникающие при неудачном удалении, игнорируются; если false или не указан, такие ошибки обрабатываются вызовом обработчика, заданного onerror, или, если он не указан, вызывается исключение.
Примечание
На платформах, поддерживающих необходимые функции, основанные на файловых дескрипторах, по умолчанию используется устойчивая к символьным ссылкам версия rmtree(). На других платформах реализация rmtree() подвержена атаке через символьные ссылки: при правильном выборе времени и обстоятельств злоумышленники могут манипулировать символьными ссылками в файловой системе, чтобы удалить файлы, к которым иначе они не могли бы получить доступ. Приложения могут использовать атрибут функции rmtree.avoids_symlink_attacks, чтобы определить, какой случай применим.
Если onerror задан, он должен быть вызываемым объектом, принимающим три параметра: function, path и excinfo.
Первый параметр, function, – это функция, вызвавшая исключение; он зависит от платформы и реализации. Второй параметр, path, – это имя пути, переданное функции function. Третий параметр, excinfo, – это информация об исключении, возвращаемая функцией sys.exc_info(). Исключения, возбуждённые внутри onerror, перехвачены не будут.
Изменено в версии 3.3: Добавлена версия, устойчивая к атакам через символические ссылки, которая используется автоматически, если платформа поддерживает функции на основе файловых дескрипторов.
- shutil.move(src, dst)¶
Рекурсивно перемещает файл или каталог (src) в другое место (dst) и возвращает путь назначения.
Если целевой объект является существующим каталогом, то src перемещается внутрь этого каталога. Если целевой объект уже существует, но не является каталогом, он может быть перезаписан в зависимости от семантики os.rename().
Если целевой объект находится в текущей файловой системе, используется os.rename(). В противном случае src копируется (с помощью shutil.copy2()) в dst, а затем удаляется. В случае символьных ссылок будет создана новая символьная ссылка, указывающая на цель src, в или как dst, и src будет удалена.
Изменено в версии 3.3: Добавлена явная обработка символических ссылок для внешних файловых систем, что адаптирует поведение к GNU mv. Теперь возвращает dst.
- shutil.disk_usage(path)¶
Возвращает статистику использования диска для указанного пути в виде именованного кортежа с атрибутами total, used и free, которые содержат общий, используемый и свободный объём в байтах.
Новое в версии 3.3.
Доступность: Unix, Windows.
- shutil.chown(path, user=None, group=None)¶
Изменяет владельца user и/или группу group для указанного path.
user может быть системным именем пользователя или uid; то же самое относится к group. Требуется хотя бы один аргумент.
См. также os.chown() – нижележащую функцию.
Доступность: Unix.
Новое в версии 3.3.
- shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)¶
Возвращает путь к исполняемому файлу, который был бы запущен, если бы была вызвана указанная cmd. Если ни одна cmd не будет вызвана, возвращает None.
mode – это маска прав доступа, передаваемая в os.access(); по умолчанию определяет, существует ли файл и является ли он исполняемым.
Если path не указан, используются результаты os.environ(), возвращающие либо значение «PATH», либо резервное значение os.defpath.
В Windows текущий каталог всегда добавляется в начало path, независимо от того, используется значение по умолчанию или предоставляется собственное, – это поведение, которое командная оболочка использует при поиске исполняемых файлов. Кроме того, при поиске cmd в path проверяется переменная окружения PATHEXT. Например, если вызвать shutil.which("python"), which() будет искать в PATHEXT, чтобы узнать, что нужно искать python.exe в каталогах path. Например, в Windows:
>>> shutil.which("python") 'C:\\Python33\\python.EXE'
Новое в версии 3.3.
- exception shutil.Error¶
Это исключение собирает исключения, возбуждённые во время операции с несколькими файлами. Для copytree() аргумент исключения представляет собой список трёхэлементных кортежей (srcname, dstname, исключение).
11.10.1.1. Пример copytree¶copytree example
Этот пример является реализацией функции copytree(), описанной выше, с опущенной строкой документации. Он демонстрирует многие другие функции, предоставляемые этим модулем.
def copytree(src, dst, symlinks=False):
names = os.listdir(src)
os.makedirs(dst)
errors = []
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks)
else:
copy2(srcname, dstname)
# XXX Что насчет устройств, сокетов и т.д.?
except OSError as why:
errors.append((srcname, dstname, str(why)))
# перехватываем ошибку от рекурсивного copytree, чтобы мы могли
# продолжить с другими файлами
except Error as err:
errors.extend(err.args[0])
try:
copystat(src, dst)
except OSError as why:
# не удается скопировать время доступа к файлам в Windows
if why.winerror is None:
errors.extend((src, dst, str(why)))
if errors:
raise Error(errors)
Другой пример, использующий вспомогательную функцию ignore_patterns():
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
Это скопирует все, кроме файлов .pyc и файлов или каталогов, имя которых начинается с tmp.
Ещё один пример, использующий аргумент ignore для добавления вызова журналирования:
from shutil import copytree
import logging
def _logpath(path, names):
logging.info('Working in %s' % path)
return [] # ничего не будет проигнорировано
copytree(source, destination, ignore=_logpath)
11.10.2. Операции архивации¶Archiving operations
Новое в версии 3.2.
Также предоставляются высокоуровневые утилиты для создания и чтения сжатых и архивных файлов. Они полагаются на модули zipfile и tarfile.
- shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])¶
Создаёт архивный файл (например, zip или tar) и возвращает его имя.
base_name – это имя создаваемого файла, включая путь, без расширения, специфичного для формата. format – это формат архива: один из «zip», «tar», «bztar» (если доступен модуль bz2) или «gztar».
root_dir – это каталог, который будет корневым каталогом архива; например, мы обычно переходим в root_dir перед созданием архива.
base_dir – это каталог, из которого начинается архивирование; т.е. base_dir будет общим префиксом всех файлов и каталогов в архиве.
root_dir и base_dir по умолчанию равны текущему каталогу.
Если dry_run равен true, архив не создаётся, но операции, которые были бы выполнены, записываются в журнал logger.
owner и group используются при создании tar-архива. По умолчанию используются текущий владелец и группа.
logger должен быть объектом, совместимым с PEP 282, обычно экземпляром logging.Logger.
Аргумент verbose не используется и является устаревшим.
- shutil.get_archive_formats()¶
Возвращает список поддерживаемых форматов архивирования. Каждый элемент возвращаемой последовательности представляет собой кортеж (name, description).
По умолчанию shutil предоставляет следующие форматы:
- gztar: tar-файл, сжатый gzip
- bztar: tar-файл, сжатый bzip2 (если доступен модуль bz2).
- tar: несжатый tar-файл
- zip: ZIP-файл
Можно зарегистрировать новые форматы или предоставить собственный архиватор для любых существующих форматов, используя register_archive_format().
- shutil.register_archive_format(name, function[, extra_args[, description]])¶
Регистрирует архиватор для формата name.
function – это вызываемый объект, который будет использоваться для распаковки архивов. Вызываемый объект получит base_name создаваемого файла, а затем base_dir (по умолчанию os.curdir), с которого начинается архивация. Остальные аргументы передаются как именованные: owner, group, dry_run и logger (как передаются в make_archive()).
Если задано, extra_args – это последовательность пар (name, value), которые будут использоваться как дополнительные именованные аргументы при вызове архиватора.
description используется get_archive_formats(), которая возвращает список архиваторов. По умолчанию – пустая строка.
- shutil.unregister_archive_format(name)¶
Удалите имя формата архива name из списка поддерживаемых форматов.
- shutil.unpack_archive(filename[, extract_dir[, format]])¶
Распаковывает архив. filename – это полный путь к архиву.
extract_dir – имя целевой директории, в которую распаковывается архив. Если не указано, используется текущая рабочая директория.
format – это формат архива: один из «zip», «tar» или «gztar». Или любой другой формат, зарегистрированный с помощью register_unpack_format(). Если не указан, unpack_archive() использует расширение имени файла архива и проверяет, зарегистрирован ли распаковщик для этого расширения. Если ни один не найден, возбуждается ValueError.
- shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])¶
Регистрирует формат распаковки. name – это имя формата, а extensions – список расширений, соответствующих формату, например .zip для Zip-файлов.
function – это вызываемый объект, который будет использоваться для распаковки архивов. Вызываемый объект будет получать путь к архиву, за которым следует каталог, в который необходимо извлечь архив.
Если указано, extra_args – это последовательность кортежей (name, value), которые будут переданы как именованные аргументы вызываемому объекту.
description может быть указан для описания формата и будет возвращён функцией get_unpack_formats().
- shutil.unregister_unpack_format(name)¶
Отменяет регистрацию формата распаковки. name – имя формата.
- shutil.get_unpack_formats()¶
Возвращает список всех зарегистрированных форматов распаковки. Каждый элемент возвращаемой последовательности – это кортеж (name, extensions, description).
По умолчанию shutil предоставляет следующие форматы:
- gztar: tar-файл, сжатый gzip
- bztar: tar-файл, сжатый bzip2 (если доступен модуль bz2).
- tar: несжатый tar-файл
- zip: ZIP-файл
Можно зарегистрировать новые форматы или предоставить собственный распаковщик для любых существующих форматов, используя register_unpack_format().
11.10.2.1. Пример архивации¶Archiving example
В этом примере создаётся tar-архив, сжатый gzip, содержащий все файлы, найденные в каталоге пользователя .ssh:
>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'gztar', root_dir)
'/Users/tarek/myarchive.tar.gz'
Полученный архив содержит:
$ tar -tzvf /Users/tarek/myarchive.tar.gz
drwx------ tarek/staff 0 2010-02-01 16:23:40 ./
-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys
-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config
-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa
-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub
-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa
-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub
-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts
11.10.3. Определение размера выходного терминала¶Querying the size of the output terminal
Новое в версии 3.3.
- shutil.get_terminal_size(fallback=(columns, lines))¶
Получить размер окна терминала.
Для каждого из двух измерений проверяется соответствующая переменная окружения: COLUMNS и LINES. Если переменная определена и её значение – положительное целое число, оно используется.
Если COLUMNS или LINES не определены (что бывает чаще всего), запрашивается терминал, подключённый к sys.__stdout__, путём вызова os.get_terminal_size().
Если размер терминала не удаётся получить – либо из-за того, что система не поддерживает запрос, либо потому, что нет подключения к терминалу, – используется значение, указанное в параметре fallback. fallback по умолчанию равен (80, 24), что является размером, используемым по умолчанию во многих эмуляторах терминала.
Возвращаемое значение – именованный кортеж типа os.terminal_size.
См. также: The Single UNIX Specification, Version 2, Другие переменные окружения.