使用filter
添加目录时,有没有办法访问tarfile.add
lambda中的各个文件名?
我正在使用tarfile
模块来创建项目目录的存档。我不再需要这些文件中的一些,我想忽略:
myproj/ # example; actual project directory structure much deeper
importantfile.txt
semi-importantfile.doc
useless-file.exe # ignore this one
我现在正在做的是使用tarfile.add
的{{1}}参数跳过exclude
。
useless-file.exe
我知道import tarfile
with tarfile.open('mytar.tar', 'w') as mytar:
mytar.add('myproj', exclude=lambda x: os.path.basename(x) == 'useless-file.exe')
现已弃用,为了防范未来,我正在尝试切换到使用新的exclude
参数。
filter
然而,这样做最终会将 mytar.add('myproj', filter=lambda x: (
x if x.name != 'useless-file.exe'
else None))
添加到tarball中。通过一些测试,我发现这是因为,虽然useless-file.exe
以递归方式提供了目录的名称及其所有内容,但exclude
仅获取明确添加的文件的filter
(在此case,目录TarInfo
)
那么有没有办法使用myproj
复制exclude
的行为?如果可能的话,我宁愿不以递归方式遍历所有目录,只是为了检查我是否添加了任何不需要的文件。
有关问题的完整说明,请参阅@ larsks的答案。我的问题是在filter
使用exclude
os.path.basename
时调用了x
(请参阅上面编辑的代码),但在使用x.name
时我忘记在filter
上执行此操作。
答案 0 :(得分:1)
我不认为for
方法的行为与您认为的方式相同。例如,如果我的目录结构如下:
filter
我运行以下代码:
example/
file0.1
file0.2
dir1/
file1.1
file1.2
我看作输出:
import tarfile
def myfilter(thing):
print('myfilter called for {thing.name}'.format(thing=thing))
return thing
t = tarfile.open('archive.tar', mode='w')
t.add('example', recursive=True, filter=myfilter)
也就是说,每个添加到存档的项目都会调用一次过滤器。如果想要排除myfilter called for example
myfilter called for example/file0.1
myfilter called for example/file0.2
myfilter called for example/dir1
myfilter called for example/dir1/file1.1
myfilter called for example/dir1/file1.2
,我会写一个看起来像这样的过滤函数:
example/dir1/file1.1
在上例中使用此作为过滤器时,生成的存档包含:
def exclude_file1(thing):
if thing.name != 'example/dir1/file1.1':
return thing
(编辑:上面的示例是使用Python 3.5测试的)