Skip to main content
 首页 » 编程设计

python之向自身添加存档时 tarfile.add() 的预期行为是什么

2025年05月04日11findumars

这个问题可能听起来很奇怪,因为我知道我强制执行了一个奇怪的情况>它是偶然出现的(一个人可能会说的错误)而且我什至知道避免它很重要,所以请跳过那部分。

我真的很想了解我看到的行为。

该函数的要点是将目录中具有给定前缀的所有文件添加到存档中。我注意到即使存在“错误”,该程序也能正常工作(原文如此!)。我想了解原因。

代码相当简单,所以我允许自己发布整个函数:

def pack(prefix, custom_meta_files = []): 
  postfix = 'tgz'   
  if prefix[-1] != '.': 
    postfix = '.tgz' 
 
  archive = tarfile.open(prefix+postfix, "w:gz") 
  files = filter(lambda path: path.startswith(prefix), os.listdir()) 
  #print('files: {0}'.format(list(files))) 
 
  for file in files: 
    print('packing `{0}`'.format(file)) 
    archive_name = file[len(prefix):]   #skip prefix + dot 
    archive.add(file, archive_name) 
 
  not_doubled_metas = set(custom_meta_files) - set(archive.getnames()) 
  print('metas to add: {0}'.format(not_doubled_metas)) 
  for meta in not_doubled_metas: 
    print('packing `{0}`'.format(meta)) 
    archive.add(meta) 
  print('contents:{0}'.format(archive.getnames())) 

正如您所注意到的,我使用 prefix 创建存档,然后通过在 cwd 中列出所有内容来创建要打包的文件列表,并通过 lambda 。文件自然会通过过滤器。如果名称不重叠,还有一个片段可以添加固定文件,尽管我认为这并不重要。

所以这种运行的输出是例如:

packing `ga_run.seq_niche.N30.1.bt0_5K.params` 
packing `ga_run.seq_niche.N30.1.bt0_5K.stats` 
packing `ga_run.seq_niche.N30.1.bt0_5K.tgz` 
metas to add: {'stats.meta'} 
packing `stats.meta` 
contents:['params', 'stats', 'stats.meta'] 

所以脚本尝试添加自己,但是它并没有出现在最终的内容中。我不知道预期的行为是什么,但根本没有警告,而且 documentation没有提到任何东西。我阅读了有关添加成员方法的部分,并使用搜索自身和同名。

我假设它会被自动跳过,但我不知道如何准确地检查它。我个人希望添加一个零长度文件作为成员,但我理解跳过,因为我实际上更有意义。

问题 tarfile.add() 中忽略将存档添加到自身是否是期望的行为?哪里说的?

请您参考如下方法:

从 3.2 到 2.4 扫描 tarfile.py 代码,它们都有类似的代码:

# Skip if somebody tries to archive the archive... 
if self.name is not None and os.path.abspath(name) == self.name: 
    self._dbg(2, "tarfile: Skipped %r" % name) 
    return