2009-06-12 7 views
7

Pickleは、特定の入力値に対して常に同じ出力を生成しますか?内容は同じだが、挿入/削除の履歴が異なる辞書を拾うときには、問題があると思われる。私の目標は、Memoize実装のために、PickleとSHA1を使用して、関数の引数の "署名"を作成することです。酸洗い工程は決定的ですか?

答えて

7

内容は同じですが、挿入/削除の履歴が異なる辞書を拾い上げるときに、問題が発生する可能性があるとします。右

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

も参照してください:pickle.dumps not suitable for hashing

私の目標は、memoizeの実装のためのピクルスとSHA1を使用して、関数の引数の "署名" を作成することです。

これには多くの根本的な問題があります。オブジェクトのアイデンティティの問題を正しく考える平等をマップオブジェクトに文字列の変換を思い付くことは不可能それをです:

>>> 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

同じ出力はどういう意味ですか?通常、ラウンドトリップ(pickling - > unpickling)には常に同じ出力が得られるはずですが、シリアライズされた書式自体はすべての条件で同じであることが保証されているとは思いません。確かに、それはプラットフォームとそのすべての間で変わるかもしれません。

メモリングのために酸洗を使用することはうまくいくはずです - 私はこのスキームを何度も問題なく使用しましたが、それはかなり簡単な問題でした。 1つの問題は、これがすべての有用なケースをカバーしていないことです(関数が気になる:あなたがそれらをピケッとすることはできないので、関数が呼び出し可能な引数を取る場合、

関連する問題