2014-03-03 42 views
1

我正在創建一個庫,它將函數返回值緩存到pkl文件。但是,有時當我在寫入pkl文件的同時終止程序時,會發現損壞的pkl文件(並非總是)。我正在設置庫來處理這些損壞的文件(主要導致EOFError,但也可能導致IOError)。但是,我需要創建我知道已經損壞的文件來測試它,並且終止程序的方法並不一致。有沒有其他的方式來寫入一個pkl文件,並保證一個EOFError或IOError,當我後來從它讀取?如何創建一個損壞的pkl文件python

+0

什麼EXAC你的意思是「腐敗」嗎? –

+0

正如我所指出的,保證(每種情況分開)在讀取時生成EOFError或IOError。 – mlstudent

+0

只需嘗試從不存在的文件「加載」。 –

回答

1

簡短回答:你不需要它們。

長答案:有一個更好的方法來處理這個問題,請看下面。

好吧,讓我們通過了解這些異常單獨啓動:

  1. 將引發EOFError發生當解析器達到文件 末尾,沒有對象的完整表示,因此,無法重建 的對象。

  2. IOError表示讀取錯誤,該文件可能被刪除或在過程中被撤銷。

現在,讓我們開發一個測試它的策略。

一個常見的習慣用法是將違規方法例如pickle.Pickler封裝爲可隨機拋出這些異常的方法。這裏有一個例子:

import pickle 
from random import random 

def chaos_pickle(obj, file, io_error_chance=0, eof_error_chance=0): 
    if random < io_error_chance: 
     raise IOError("Chaotic IOError") 

    if random < eof_error_chance: 
     raise EOFError("Chaotic EOFError") 

    return pickle.Pickler(obj, file) 

使用它來代替傳統的pickle.Pickler確保您的代碼中隨機拋出兩個異常的(注意,有一點需要注意,不過,如果你設置io_error_chance 1,它永遠不會養EOFError

這一招沿着模擬庫(unittest.mock)用於測試目的創建錯誤的對象時是非常有用的。

享受!

+0

我相信這些錯誤實際上來自'pickle'本身,而不是文件。當我嘗試去除一個截斷的pickle時,我得到的'EOFError'來自'pickle'模塊中'lo​​ad_eof'。 – user2357112

+0

嗨!同樣的策略也適用,你可以用'pickle'(或任何函數/方法)來隨機拋出異常並確保你的代碼處理好它們。這是一個非常常見的Python測試配方。 – rafgoncalves

+0

EOFError意味着「流意外結束」,它真的不在乎它是一個字符串,文件還是其他任何東西。 IOError的意思是「我無法讀取你給我的描述符,直到有效的EOF」。 – rafgoncalves

1

拿一堆舊的,腐敗的泡菜並使用它們。如果你沒有,可以拿一堆工作泡菜,準確地隨機截斷它們,當你嘗試加載它們時,看看哪些錯誤會出錯。或者,如果「腐敗」文件甚至不需要像有效的泡菜一樣,那麼您可以解開隨意的廢話,而這種廢話不會有效。例如,混合鍵盤並嘗試取消結果。

注意,docs

pickle模塊並非意在對抗錯誤或 惡意構造的數據安全。切勿取消從 不受信任或未經身份驗證的來源收到的數據。

+0

我現在沒有任何權利,在寫之前我刪除了它們。這是否意味着我需要在寫入文件時終止,直到最終導致一些損壞? – mlstudent

+0

@AlexanderMoreno:你也可以醃一根弦,把弦切成兩半,看看結果是否是一個無效的醃菜,或者甚至試着去除隨機垃圾,比如'apoiweroapwhoqiw'或者GIFs。 – user2357112