1

変更可能なオブジェクトをハッシュできないことは理解していますが、特に期待どおりに比較できることを考えると、変更可能なオブジェクトのメソッドにもこれが当てはまるのはなぜですか?

例えば:

>>> d1, d2 = {}, {}
>>> d1.keys == d2.keys
False
>>> set([d1.keys])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

この例でd1.keysは、それ自体はdict例外が不平を言っているわけではありません。dictユーザーが作成したクラスのインスタンスは、デフォルトでハッシュ可能であり、属性を持っているため、単純に属性として a を持つことは、明らかにハッシュ可能であることの一般的な障害にはなりません__dict____self__メソッド オブジェクト自体は、コンポーネントが変更可能かどうかにかかわらず、その有効期間にわたって意味のある方法で変更されることはありません。変更可能なオブジェクトのハッシュ メソッドが、ハッシュによって暗示されたコントラクトを破るのを見ていない方法はありますか?

以下は、メソッドがハッシュ可能であることを保証し、通常のメソッドオブジェクトでもうまく機能するラッパーでの私の試みです。通常はハッシュ不可能なメソッドの場合、メソッド実装オブジェクトとメソッドの__self__コンポーネントの ID を含むタプルからハッシュ値が計算されます。これが私に爆発する理由はありますか?

class HashableMethod(object):
    __slots__ = ['_method', '_hashval', '__weakref__']

    def __init__(self, method):
        self._method = method

    def __getattr__(self, name):
        return getattr(self._method, name)

    def __call__(self, *args, **kwds):
        return self._method(*args, **kwds)

    def __eq__(self, other):
        return self._method == other

    def __hash__(self):
        try:
            return self._hashval
        except AttributeError: # self._hashval is not yet calculated
            pass

        meth = self._method
        try:
            hashval = self._hashval = hash(meth)
        except TypeError: # self._method is not ordinarily hashable
            obj = meth.__self__
            try:
                func = meth.__func__
            except AttributeError: # self._method is builtin
                func = getattr(type(obj), meth.__name__)
            hashval = self._hashval = hash((func, id(obj)))
        return hashval
4

0 に答える 0