如何为shutil.copytree编写一个忽略的回调函数

8

我对Python比较新。我正在尝试复制一个目录到另一个目录并保持结构。

我正在使用

    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
4个回答

7
忽略函数的返回值需要是一个要忽略的目录和文件列表。你没有返回任何内容,这相当于返回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

1
你的意思是 return [f for f in files if not is_dir(os.path.join(folder, f)) and f not in copy_these] - Fred Foo
3
好的列表推导式。但是,由于提问者说他是Python新手,采用更详细的风格可能更易于理解和适应。 - jwhitlock

6
shutil 模块提供了一个 ignore_patterns 函数。

该工厂函数创建一个可以用作 copytree() 的 ignore 参数的可调用函数,忽略与提供的 glob 样式模式之一匹配的文件和目录。

该模块页面还展示了几个示例

如果您想忽略某个文件类型(这正是我所需要的),那么这将完美地运行。 - Steve Miskiewicz

0
如果给定了ignore参数,它必须是一个可调用的函数,该函数将以当前正在访问的目录和其内容的列表作为参数。这个可调用函数必须返回一个相对于当前目录的目录和文件名的序列;在复制过程中,这些名字将被忽略。

(docs)

我的目标是接收一个文件列表,并使用匿名函数(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对目录处理的贡献。

0
忽略回调函数应返回相对于“src”目录不应被复制的名称列表。
您的示例回调未返回任何内容(即None)。然后,copytree期望一个列表,尝试迭代它。由于无法这样做,因此会出现异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接