gpt4 book ai didi

python - 使用单个文件名过滤 tarfile.add

转载 作者:行者123 更新时间:2023-12-01 02:31:51 25 4
gpt4 key购买 nike

使用 tarfile.add 添加目录时,是否可以访问 filter lambda 中的各个文件名?

我正在使用 tarfile 模块来创建项目目录的存档。其中一些文件我不再需要,我想忽略:

myproj/  # example; actual project directory structure much deeper
importantfile.txt
semi-importantfile.doc
useless-file.exe # ignore this one

我现在正在做的是使用tarfile.addexclude参数来跳过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 现已弃用,为了面向 future ,我尝试改用新的 filter 参数。

    mytar.add('myproj', filter=lambda x: (
x if x.name != 'useless-file.exe'
else None))

但是,这样做最终会将 useless-file.exe 添加到 tarball 中。通过一些测试,我发现这是因为,虽然 exclude 递归地输入目录名称及其所有内容,但 filter 只获取 TarInfo对于显式添加的文件(在本例中为目录 myproj)

那么有没有办法使用filter复制我在exclude中的行为?如果可能的话,我真的不想递归地遍历所有目录,只是为了检查我没有添加任何不需要的文件。

解决方案说明

请参阅@larsks 的回答以获取问题的完整说明。我的问题是,当使用 exclude 时,我在 x 上调用了 os.path.basename (请参阅上面编辑过的代码),但我忘了在使用过滤器时的x.name

最佳答案

我认为 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

当在上面的示例中使用它作为过滤器时,生成的存档包含:

$ tar tf archive.tar 
example/
example/file0.1
example/file0.2
example/dir1/
example/dir1/file1.2

(编辑:上面的例子是用Python 3.5测试的)

关于python - 使用单个文件名过滤 tarfile.add,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46734601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com