Как скопировать каталог и его содержимое в существующее место с помощью Python?

Я пытаюсь скопировать каталог и все его содержимое на уже существующий путь. Проблема в том, что между модулем os и модулем Shutil нет способа сделать это. функция shutil.copytree() ожидает, что путь назначения заранее не существует.

Точный результат, который я ищу, - это скопировать всю структуру папок поверх другой, молча перезаписывая любые найденные дубликаты. Прежде чем я прыгну и начну писать свою собственную функцию для этого, я подумал, что хотел бы спросить, знает ли кто-нибудь о существующем рецепте или фрагменте, который делает это.


person Soviut    schedule 04.02.2009    source источник


Ответы (4)


distutils.dir_util.copy_tree делает то, что вам нужно.

Скопируйте все дерево каталогов src в новое место dst. И src, и dst должны быть именами каталогов. Если src не является каталогом, вызовите DistutilsFileError. Если dst не существует, он создается с помощью mkpath(). Конечным результатом копирования является то, что каждый файл в src копируется в dst, а каталоги в src рекурсивно копируются в dst. Возвращает список файлов, которые были скопированы или могли быть скопированы, используя их выходное имя. Возвращаемое значение не зависит от update или dry_run: это просто список всех файлов в src с именами, измененными на dst.

(дополнительная документация по указанному выше URL)

person Ali Afshar    schedule 04.02.2009
comment
Такого еще не видел, хорошая находка. Мое единственное предостережение заключается в том, что он не указывает, какие файлы были перезаписаны, а какие были созданы заново. Однако, пока это не является обязательным требованием, это выглядит идеально. - person Ben Blank; 04.02.2009
comment
Это хороший вариант, хотя для этого потребуется установить distutils. Не такая уж большая проблема, так как мы все равно объединяем это в EXE с pyinstaller. - person Soviut; 04.02.2009
comment
distutils является частью стандартной библиотеки, поэтому теоретически должен быть установлен всегда. - person Ali Afshar; 04.02.2009
comment
я пытался использовать distutils и получил ошибку: mkpath: 'имя' должно быть строкой (получил ['/tmp/2']) будет ли это работать со списком? - person kamal; 04.02.2012

Почему бы не реализовать это самостоятельно с помощью os.walk?

person Swaroop C H    schedule 04.02.2009
comment
это то, что я рассматривал, но я хотел убедиться, что не изобретаю велосипед. - person Soviut; 04.02.2009

Для подобных файловых операций высокого уровня используйте модуль shutil и, в вашем случае, функцию copytree. Я думаю, что это чище, чем «злоупотребление» distutils.

ОБНОВЛЕНИЕ:: Забудьте об ответе, я упустил из виду, что ОП действительно пытался Shutil.

person André    schedule 04.02.2009
comment
В своем вопросе я упомянул, что Shutil.copytree() - это то, что я пытался использовать, но не отвечал всем требованиям. - person Soviut; 05.02.2009
comment
Обычно я согласен с этим, но это не совсем то, о чем просил ОП. - person Ali Afshar; 07.02.2009
comment
Вы, ребята, правы, я проглядел это в вопросе, в тот вечер было слишком поздно :-) - person André; 07.02.2009

Вы получаете сообщение об ошибке «Невозможно создать каталог, когда он уже существует»? Я не уверен, насколько это глупо, но все, что я сделал, это вставил одну строку в модуль copytree: я изменил:

def copytree(src, dst, symlinks=False):
    names = os.listdir(src)
    os.makedirs(dst)

в:

def copytree(src, dst, symlinks=False):
    names = os.listdir(src)
    if (os.path.isdir(dst)==False):
        os.makedirs(dst)       

Кажется, я сделал бладер. Если да, может ли кто-нибудь указать мне на это? Извините, я очень новичок в python: P

person Community    schedule 05.03.2009