python shutil.copytree()的Ignore回调不接受完整路径

时间:2013-07-09 17:33:50

标签: python ignore shutil copytree

我想在调用shutil.copytree()时指定可忽略文件和目录的完整路径。像

这样的东西
def my_ignore(dir, files):

    # return ["exclude.file"] # working

    return ["/full_path_to/exclude.file"] # Not working

shutil.copytree(src, dest, ignore=my_ignore)

在此之后,排除的文件仍然存在,除非我只返回文件名而不是完整路径。问题是我真的想在不同的目录下设置一个特定的文件,而不是所有匹配的文件名。

我在这里提到了一些问题,例如: How to write a call back function for ignore in shutil.copytree

Filter directory when using shutil.copytree?

但没有一个答案有效。看起来,ignore钩子只能返回一个glob样式,任何构造的完整路径都不起作用。

我错过了什么吗?

2 个答案:

答案 0 :(得分:1)

ignore确实必须只返回被忽略的文件名。但是,为每个目录shutil.copytree()访问调用该函数;你可以忽略每个目录的文件

如果您有一个需要忽略的文件的完整路径,那么匹配传递给ignore函数的第一个参数;它是该目录的完整路径:

def my_ignore(dir, files):
    if dir == '/full_path_to':
        return {"exclude.file"}

我在这里归还一套;设置成员资格测试比列表更快。

如果您有一组要忽略的预定义路径,请将其解析为字典; keys是目录路径,该路径中文件名的值集:

from collections import defaultdict

to_ignore = defaultdict(set)
for path in ignored_paths:
    dirname, filename = os.path.split(path)
    to_ignore[dirname].add(filename)

def my_ignore(src, files):
    return to_ignore.get(src, set())

答案 1 :(得分:1)

这不是魔术。 copytree()一次复制一个目录的内容,它专门在您返回的忽略列表中查找文件名。完整路径永远不是文件的名称,因此永远不会匹配。

但是,dir参数可以帮助您按照自己的意愿执行操作:

def my_ignore(dir, files):
    if dir == "/full/path/to":
        return ["exclude.file"]
    else:
        return []