2009-06-12 44 views
7

酸菜總是會爲某個輸入值產生相同的輸出嗎?我想在酸洗含有相同內容但插入/刪除歷史不同的字典時可能會遇到一些問題。我的目標是創建一個函數參數的「簽名」,使用Pickle和SHA1來實現記憶。酸洗過程是否具有確定性?

回答

7

我想在酸洗含有相同內容但插入/刪除歷史記錄不同的字典時可能會出現問題。

右:

>>> pickle.dumps({1: 0, 9: 0}) == pickle.dumps({9: 0, 1: 0}) 
False 

參見:pickle.dumps not suitable for hashing

我的目標是創建一個函數參數 「簽名」,用泡菜和SHA1,對於memoize的實現。

這有一些基本問題。這是不可能拿出一個對象 - 字符串轉換映射平等的正確思考的對象身份的問題:根據您的具體要求

>>> a = object() 
>>> b = object() 
>>> a == b 
False 
>>> pickle.dumps(b) == pickle.dumps(a) 
True 

,你可能能夠對象層次轉變成那些你可以然後哈希:

def hashablize(obj): 
    """Convert a container hierarchy into one that can be hashed. 

    Don't use this with recursive structures! 
    Also, this won't be useful if you pass dictionaries with 
    keys that don't have a total order. 
    Actually, maybe you're best off not using this function at all.""" 
    try: 
     hash(obj) 
    except TypeError: 
     if isinstance(obj, dict): 
      return tuple((k, hashablize(v)) for (k, v) in sorted(obj.iteritems())) 
     elif hasattr(obj, '__iter__'): 
      return tuple(hashablize(o) for o in obj) 
     else: 
      raise TypeError("Can't hashablize object of type %r" % type(obj)) 
    else: 
     return obj 
0

你是什麼意思相同的產出?你通常應該總是得到相同的輸出(酸洗 - >去除),但我不認爲序列化格式本身在每種情況下都是一樣的。當然,它可能會在平臺之間發生變化。

在您的程序的一次運行中,使用酸洗進行記憶應該沒問題 - 我已經多次使用這個方案沒有麻煩,但那是非常簡單的問題。一個問題是,這並不包括每一個有用的案例(功能浮現在腦海中:你不能醃製它們,所以如果你的函數需要一個可調用的參數,那將不起作用)。