7

pickle.dumps任意の Python オブジェクトのハッシュを作成するために使用してきましたが、dict/set の順序が正規化されていないため、結果が信頼できないことがわかりました。

SO およびその他の場所には関連する質問いくつか ありますが、同等性 ( /結果)に同じ基準を使用するハッシュアルゴリズムを見つけることができないようです。私は自分でロールするための基本的な要件を理解していますが、明らかに、テスト済みのものを使用したいと思っています。 __getstate____dict__

そのようなライブラリは存在しますか?私が実際に求めているのは、出力をハッシュできるように( __getstate__and を使用して) オブジェクトを決定論的にシリアル化するライブラリだと思います。__dict__

編集

hash明確にするために、Python (または)によって返される値とは異なるものを探しています__hash__。私が欲しいのは、本質的に、ハッシュ可能であるかどうかにかかわらず、任意のオブジェクトのチェックサムです。この値は、オブジェクトの状態によって異なります。(私は「状態」を使用して、返された dict を参照します。__getstate__それが存在しない場合は、オブジェクトの__dict__.)

4

2 に答える 2

1

Pickler を拡張し、select 関数をオーバーライドして必要な型を正規化できることに気がついたので、それを実行しています。外観は次のとおりです。

from copy import copy
from pickle import Pickler, MARK, DICT
from types import DictionaryType


class CanonicalizingPickler(Pickler):
    dispatch = copy(Pickler.dispatch)

    def save_set(self, obj):
        rv = obj.__reduce_ex__(0)
        rv = (rv[0], (sorted(rv[1][0]),), rv[2])
        self.save_reduce(obj=obj, *rv)

    dispatch[set] = save_set

    def save_dict(self, obj):
        write = self.write
        write(MARK + DICT)

        self.memoize(obj)
        self._batch_setitems(sorted(obj.iteritems()))

    dispatch[DictionaryType] = save_dict
于 2013-05-30T01:51:10.563 に答える
0

ハッシュ値を計算 (および保存) したら、オブジェクトを不変として扱うと仮定します。それ以外の場合は、何をしているかに非常に注意する必要があります (たとえば、セットや dict などに格納するためにハッシュ可能性の品質を使用しないでください)。

とはいえ、最もエレガントな方法は、オブジェクトのすべてのメンバーを__dict__最初にハッシュ可能な型に格納することです。s の代わりにlist、(もちろん、ハッシュ可能なオブジェクトの) タプルを使用します。dicts の代わりに、この質問に対する解決策のいずれかを hashable-dict タイプとして使用してください (私は個人的に @alex のものを使用しています)。繰り返しますが、これが機能するには、キーと値の両方がハッシュ可能である必要があります。

次に、__hash__メソッドは、次のように、使用しているのと同じ hashable-dict を使用できます。

def _hashable_state(self):
    return MyHashableDict(self.__dict__)
def __hash__(self):
    return hash(self._hashable_state())
def __reduce__(self):
    return self._hashable_state()
于 2013-04-23T05:41:43.780 に答える