Документация Python неофициальный перевод
Содержание страницы

shutil – высокоуровневые операции с файламиshutil – High-level file operations

Исходный код: Lib/shutil.py


Модуль shutil предоставляет ряд высокоуровневых операций с файлами и наборами файлов. В частности, предоставлены функции, которые поддерживают копирование и удаление файлов. Для операций с отдельными файлами см. также модуль os.

Предупреждение

Даже функции копирования файлов высокого уровня (shutil.copy(), shutil.copy2()) не могут скопировать все метаданные файла.

На платформах POSIX это означает, что владелец и группа файла теряются, а также ACL. На Mac OS не используются ресурсные форки и другие метаданные. Это означает, что ресурсы будут потеряны, а коды типа и создателя файла будут некорректными. В Windows владельцы файлов, ACL и альтернативные потоки данных не копируются.

Операции с каталогами и файлами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)

Эта фабричная функция создаёт функцию, которую можно использовать как вызываемый объект для аргумента ignore функции copytree(), игнорируя файлы и каталоги, соответствующие одному из предоставленных шаблонов в стиле glob. См. пример ниже.

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, если файл, на который указывает символическая ссылка, не\ nсуществует, исключение будет добавлено в список ошибок, вызываемых в исключении 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: Добавлена версия, устойчивая к атакам через символические ссылки, которая используется автоматически, если платформа поддерживает функции на основе файловых дескрипторов.

Указывает, предоставляют ли текущая платформа и реализация версию rmtree(), устойчивую к атакам через символические ссылки. В настоящее время это верно только для платформ, поддерживающих функции доступа к каталогам на основе файловых дескрипторов.

Новое в версии 3.3.

shutil.move(src, dst, copy_function=copy2)

Рекурсивно перемещает файл или каталог (src) в другое место (dst) и возвращает путь назначения.

Если назначение – существующий каталог, то src перемещается внутрь этого каталога. Если назначение уже существует, но не является каталогом, оно может быть перезаписано в зависимости от семантики os.rename().

Если назначение находится в той же файловой системе, то используется os.rename(). В противном случае src копируется в dst с помощью copy_function и затем удаляется. В случае символических ссылок будет создана новая символическая ссылка, указывающая на цель src, в или как dst, а src будет удалён.

Если задан copy_function, это должен быть вызываемый объект, принимающий два аргумента src и dst, и будет использован для копирования src в dest, если os.rename() не может быть использована. Если исходный объект является каталогом, вызывается copytree(), и ему передаётся copy_function(). Значение по умолчанию для copy_functioncopy2(). Использование copy() в качестве copy_function позволяет выполнить перемещение, когда невозможно также скопировать метаданные, ценой отказа от копирования любых метаданных.

Изменено в версии 3.3: Добавлена явная обработка символических ссылок для внешних файловых систем, что адаптирует поведение к GNU mv. Теперь возвращает dst.

Изменено в версии 3.5: Добавлен именованный аргумент copy_function.

shutil.disk_usage(path)

Возвращает статистику использования диска для заданного пути в виде именованного кортежа с атрибутами total, used и free, которые представляют собой общий, используемый и свободный объём в байтах. В Windows path должен быть каталогом; в Unix это может быть файл или каталог.

Новое в версии 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, исключение).

Пример copytreecopytree 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)

Пример rmtreermtree example

В этом примере показано, как удалить дерево каталогов в Windows, когда у некоторых файлов установлен бит «только для чтения». Он использует колбэк onerror для снятия бита только для чтения и повторной попытки удаления. Любые последующие ошибки будут распространяться.

import os, stat
import shutil

def remove_readonly(func, path, _):
    "Clear the readonly bit and reattempt the removal"
    os.chmod(path, stat.S_IWRITE)
    func(path)

shutil.rmtree(directory, onerror=remove_readonly)

Операции архивированияArchiving operations

Новое в версии 3.2.

Изменено в версии 3.5: Добавлена поддержка формата xztar.

Также предоставляются высокоуровневые утилиты для создания и чтения сжатых и архивных файлов. Они основаны на модулях zipfile и tarfile.

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])

Создаёт архивный файл (например, zip или tar) и возвращает его имя.

base_name – имя создаваемого файла, включая путь, без формато-специфического расширения. format – формат архива: один из «zip» (если доступен модуль zlib), «tar», «gztar» (если доступен модуль zlib), «bztar» (если доступен модуль bz2) или «xztar» (если доступен модуль lzma).

root_dir – это каталог, который будет корневым каталогом архива; все пути в архиве будут относительными по отношению к нему; например, перед созданием архива обычно выполняется chdir в root_dir.

base_dir – это каталог, из которого начинается архивация; т. е. base_dir будет общим префиксом для всех файлов и каталогов в архиве. base_dir должен быть указан относительно root_dir. См. Пример архивации с base_dir о том, как использовать base_dir и root_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 предоставляет следующие форматы:

  • zip: ZIP-файл (если доступен модуль zlib).

  • tar: несжатый tar-файл.

  • gztar: tar-файл, сжатый gzip (если доступен модуль zlib).

  • bztar: tar-файл, сжатый bzip2 (если доступен модуль bz2).

  • xztar: tar-файл, сжатый xz (если доступен модуль lzma).

Можно зарегистрировать новые форматы или предоставить собственный архиватор для любого существующего формата, используя 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», «bztar» или «xztar». Или любой другой формат, зарегистрированный с помощью register_unpack_format(). Если формат не указан, unpack_archive() будет использовать расширение имени файла архива и проверит, зарегистрирован ли распаковщик для этого расширения. Если ничего не найдено, вызывается ValueError.

Изменено в версии 3.7: Принимает объект, подобный пути для filename и extract_dir.

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 предоставляет следующие форматы:

  • zip: ZIP-файл (распаковка сжатых файлов работает, только если доступен соответствующий модуль).

  • tar: несжатый tar-файл.

  • gztar: tar-файл, сжатый gzip (если доступен модуль zlib).

  • bztar: tar-файл, сжатый bzip2 (если доступен модуль bz2).

  • xztar: tar-файл, сжатый xz (если доступен модуль lzma).

Вы можете зарегистрировать новые форматы или предоставить собственный распаковщик для любых существующих форматов, используя register_unpack_format().

Пример архивации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

Пример архивации с base_dirArchiving example with base_dir

В этом примере, аналогичном предыдущему, показано, как использовать make_archive(), но на этот раз с применением base_dir. Теперь структура каталогов выглядит так:

$ tree tmp
tmp
└── root
    └── structure
        ├── content
            └── please_add.txt
        └── do_not_add.txt

В итоговый архив должен быть включён please_add.txt, а do_not_add.txt – нет. Поэтому используется следующее:

>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> make_archive(
...     archive_name,
...     'tar',
...     root_dir='tmp/root',
...     base_dir='structure/content',
... )
'/Users/tarek/my_archive.tar'

Вывод списка файлов в полученном архиве даёт:

$ python -m tarfile -l /Users/tarek/myarchive.tar
structure/content/
structure/content/please_add.txt

Запрос размера выходного терминалаQuerying the size of the output terminal

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, Другие переменные окружения.

Новое в версии 3.3.