0

I want to derive a class from list, add a few instance attributes to it, and make it hashable. What is a good (fast and neat) way to do it?

UPDATE:

I deleted a lengthy explanation of a use case. I also moved a related but separate issue into a different question.

4

3 に答える 3

1

このコードは問題ありません。リストのコピーを作成していますが、少し時間がかかる可能性があります。

def __hash__(self):
    return hash(tuple(self.list_attribute))

より速くしたい場合は、いくつかのオプションがあります。

  • リストではなくタプルlist_attributeとして保存します(完全に構築された後)
  • 初期化時にハッシュを1回計算し、ハッシュ値を保存します。クラスは不変であり、ハッシュが変更されることはないため、これを行うことができます。
  • 独自のハッシュ関数を作成します。これがタプルのハッシュ関数です。同様のことをしてください。
于 2012-04-20T21:32:39.380 に答える
1

これは答えというよりはコメントですが、コメントするには長すぎます。これは、内部からインスタンス属性にアクセスする方法です__new__:

class Data(tuple):
    def __new__(klass, arg):
        data_inst = tuple.__new__(klass, arg)
        data_inst.min = min(data_inst)
        data_inst.max = max(data_inst)
        return data_inst

>>> d = Data([1,2,3,4])
>>> d
(1, 2, 3, 4)
>>> d.min
1
>>> d.max
4
>>> d1 = Data([1,2,3,4,5,6])
>>> d1.max
6
>>> d.max
4
于 2012-04-20T22:21:32.463 に答える
1

あなたはに適用することができtupleますself:

class State(list):
    def __hash__(self):
        return hash((self.some_attribute, tuple(self)))

tuple-ingselfには、ハッシュ プロセス全体の約半分の時間がかかります。

from timeit import timeit

setup = "from __main__ import State; s = State(range(1000)); s.some_attribute = 'foo'"
stmt = "hash(s)"
print(timeit(stmt=stmt, setup=setup, number=100000))

setup = "r = list(range(1000))"
stmt = "tuple(r)"
print(timeit(stmt=stmt, setup=setup, number=100000))

版画

0.9382011891054844
0.3911763069244216
于 2012-04-20T22:01:16.627 に答える