Как написать функцию обратного вызова для игнорирования в Shutil.copytree

Я относительно новичок в питоне. Я пытаюсь скопировать каталог в другой каталог, сохраняя структуру.

Я использую

    shutil.copytree(src, dst, symlinks=False, ignore=None, 
    copy_function=copy2, ignore_dangling_symlinks=False)

Я пытаюсь написать функцию обратного вызова для игнорирования.

Моя цель - взять список файлов в списке и скопировать только эти файлы, игнорируя остальные. Как передать список в функцию обратного вызова?

Я написал простую функцию обратного вызова, но при попытке запустить функцию copyTree получаю ошибку.

   def abc(src,names):
    print(src)
    print(names)



    Traceback (most recent call last):
   File "<pyshell#23>", line 1, in <module>
shutil.copytree('D:\Mytest','D:\PythonTestDest3',symlinks=False,ignore=abc)
  File "C:\Python32\lib\shutil.py", line 204, in copytree
if name in ignored_names:
  TypeError: argument of type 'NoneType' is not iterable

person user2434    schedule 10.08.2011    source источник


Ответы (4)


Возврат функции ignore должен быть списком каталогов и файлов, которые следует игнорировать. Вы ничего не возвращаете, что возвращает None, поэтому вы получаете ошибку TypeError: argument of type 'NoneType' is not iterable.

Вот пример, который скопирует структуру папок и файлы, перечисленные в «copy_these»:

import os.path

copy_these = ['a.txt', 'b.txt', 'c.txt']

def ignore_most(folder, files):

    ignore_list = []
    for file in files:
       full_path = os.path.join(folder, file)
       if not os.path.isdir(full_path):
           if file not in copy_these:
               ignore_list.append(file)
    return ignore_list
person jwhitlock    schedule 10.08.2011
comment
Вы имеете в виду return [f for f in files if not is_dir(os.path.join(folder, f)) and f not in copy_these]. - person Fred Foo; 10.08.2011
comment
Хорошее понимание списка. Но, поскольку спрашивающий сказал, что он новичок в Python, более подробный стиль может быть проще для понимания и адаптации. - person jwhitlock; 10.08.2011

Модуль shutil предоставляет ignore_patterns.

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

Страница модуля также показывает пару примеров.

person miku    schedule 10.08.2011
comment
Это отлично работает, если вы пытаетесь игнорировать тип файла (это то, что я искал). - person Steve Miskiewicz; 14.01.2014

Функция обратного вызова ignore должна возвращать список имен относительно каталога 'src', который не следует копировать.

Ваш пример обратного вызова ничего не возвращает (т.е. None). Затем copytree, ожидая список, пытается перебрать его. Поскольку это невозможно, вы получаете это исключение.

person Senko Rašić    schedule 10.08.2011

Если указано ignore, это должен быть вызываемый объект, который будет получать в качестве аргументов посещаемый каталог... и список его содержимого... Вызываемый объект должен возвращать последовательность имен каталогов и файлов. относительно текущего каталога ...; эти имена затем будут игнорироваться в процессе копирования.

(документы)

Моя цель - взять список файлов в списке

Попробуйте анонимную функцию (lambda) и понимание списка:

copytree(src, dest,
         ignore=lambda d, files: [f for f in files
                                    if f not in files_to_copy
                                    and not is_dir(os.path.join(d, f))])

Обратите внимание, что функция lambda получает базовые имена файлов и каталогов, а не их полные пути; спасибо @jwhitlock за работу с каталогами.

person Fred Foo    schedule 10.08.2011