2013-07-24 48 views
2

這個問題可能聽起來很奇怪,因爲我知道我強制執行一個奇怪的情況>它是偶然發生的(一個可能會說的錯誤),我甚至知道它很熱,所以請跳過那部分。將檔案添加到自身時,tarfile.add()的期望值是多少?

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

該函數的要點是將具有給定前綴的所有文件添加到存檔中。我注意到即使有一個「bug」,程序也能正常工作(原文如此!)。我想明白爲什麼。

中的代碼非常簡單,所以我允許自己發佈全功能:

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進行過濾。檔案自然會通過過濾器。如果名稱不重疊,還有一個片段可以添加固定文件,但我認爲這並不重要。

所以從這樣運行的結果是e.g:

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沒有提及任何事情。我閱讀了有關添加成員的方法的部分,並使用了搜索itselfsame name

我會認爲它會自動跳過,但我不知道如何進行實際檢查。我個人希望將零長度文件添加爲成員,但是我明白跳過了,因爲我實際上更有意義。

問題tarfile.add()中忽略將存檔添加到自身中是否是期望的行爲?它在哪裏說的?

回答

1

掃描tarfile.py代碼從3.2到2.4它們都具有類似的代碼:

# 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 
+0

我可以檢查的來源,確實如此。現在我想知道'self._dbg(2,「tarfile:Skipped%r」%name)'去哪裏了。我沒看見它。我也覺得它可以被記錄下來,但可能是一個相當小的問題。但是,我認爲等效的shell命令行爲有所不同。例如。 [超級用戶:tar如何忽略存檔本身](http://superuser.com/questions/85699)。因此,儘管我犯了一個錯誤=),但我爲什麼這麼做很困惑。 – luk32