Страницы

Поиск по вопросам

суббота, 15 февраля 2020 г.

Различия copy функций в shutil

#python #python_3x #shutil


Есть библиотека Python3 shutil с методами:


copyfileobj
copyfile
copymode
copystat
copy
copy2
copytree
ignore_patterns


Вопросы:


В чём разница между этими методами? Кратко, если не трудно объясните в какой ситуации
каждый применяется?
Например не очень понятно как копируются метаданные без самого файла, куда именно?
И наоборот файлы отдельно от метаданных, откуда тогда метаданные берутся?
Если нужно обычное копирование файла, то что из этого использовать?

    


Ответы

Ответ 1



(1) В чём разница между этими методами? Кратко если не трудно объясните в какой ситуации каждый применяется? Если чтение документации shutil.copyfileobj()не достаточно для вас, то можно посмотреть на исходный код: def copyfileobj(fsrc, fdst, length=16*1024): """copy data from file-like object fsrc to file-like object fdst""" while 1: buf = fsrc.read(length) if not buf: break fdst.write(buf) То есть: пытаемся прочитать кусок, заданной длины, из входного файла и если что-то прочитали, то пишем это в выходной файл, иначе завершаем цикл — всё. Можно использовать для копирования содержимого между любыми файло-подобными объектами (с методами read(), write()). copyfile() принимает пути, а не сами файлы (отсюда отличия). Если на входе пути к обычным файлам, то copyfile(src, dst) сводится к простому: with open(src, 'rb') as fsrc: with open(dst, 'wb') as fdst: copyfileobj(fsrc, fdst) Открыли файлы, скопировали содержимое. (2) Например не очень понятно как копируются метаданные без самого файла, куда именно? И наоборот файлы отдельно от метаданных, откуда тогда метаданные берутся? copymode(), copystat() сводится к чтению метаданных исходного файла и применению их к выходному файлу (копирование режима доступа против копирования режима доступа + времени доступа/изменения + флаги, то есть просто chmod против utime + chmod + chflags + setxattr соответственно). Документация явно говорит, что конкретно должно быть скопировано. Если выходной файл не существует, то не к чему применять метаданные и эти функции завершатся с ошибкой (FileNotFoundError). Само содержимое файлов, кто владелец, группа, к которой файл принадлежит, не меняются этими функциями. Когда явно не копируются метаданные, то используются значения по умолчанию (к примеру, может зависеть от значения umask). (3) Если нужно обычное копирование файла, то что из этого использовать? Это зависит от того какой смысл вы вкладываете в слова "обычное копирование". copy() и copy2() это просто copyfile() вызов, за которым идёт copymode() и copystat() соответственно. Дополнительно, эти функции в отличии от copyfile() могут принимать папку куда писать. Документация явно упоминает, что copy(src, dst) это cp src dst, а copy2(src, dst) это cp -p src dst. Вторая команда больше метаданных старается скопировать: разрешения на чтение/запись/исполнение, владелец, время модификации/доступа (copy2() в отличии от cp -p не копирует владельца). copytree() рекурсивно копирует всё дерево директорий, так что тяжело её перепутать с другими функциями. copytree() по умолчанию использует copy_function=copy2 для копирования обычных файлов. ignore_patterns(*patterns) возвращает функцию, которая может быть использована в качестве значения ignore параметра при вызове copytree() (ignore(src, names) функция возвращает те имена из names=os.listdir(src), которые не должны копироваться из src директории, соответствующей текущему рекурсивному вызову). Полезно на примеры посмотреть: copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*')) source папка рекурсивно копируется в новую destination папку, игнорируя имена с расширением .pyc или начинающиеся на tmp (glob-шаблоны, как в командной строке).

Ответ 2



copyfile копирует только данные,в то время как copy копирует ещё бит разрешений. Copyfile работает быстрее copy. Copyfile () вызывает метод copyfileobj (), тогда как copy () работает путем вызова функций copyfile () и copystat (). Вызов shutil.copytree() создает новую папку с именем my_scripts_backup с тем же содержимым, что и исходная папка my_scripts. Например : import shutil, os os.chdir('C:\\') shutil.copytree('C:\\my_scripts', 'C:\\my_scripts_backup')

Комментариев нет:

Отправить комментарий