109

Pythonでユーザー定義クラスをソート可能および/またはハッシュ可能にするときに、どのメソッドをオーバーライド/実装する必要がありますか?

注意すべき落とし穴は何ですか?

インタープリターに入力dir({})して、組み込みの dict のメソッドのリストを取得します。それらのうち、いくつかのサブセットを実装する必要があると思います

['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__']

Python2 とは対照的に、Python3 で実装する必要があるメソッドに違いはありますか?

4

4 に答える 4

114

私はこれを他の回答へのコメントとしてほとんど投稿しましたが、それ自体が実際の回答です。

アイテムをソート可能にするには、実装するだけです__lt__。これは、組み込みの並べ替えで使用される唯一の方法です。

他の比較 orfunctools.total_orderingは、実際にクラスで比較演算子を使用する場合にのみ必要です。

アイテムをハッシュ可能にするには__hash__、他の人が指摘したように実装します。また、互換性のある方法で実装する必要があります__eq__。同等のアイテムは同じものをハッシュする必要があります。

于 2011-08-22T19:50:51.437 に答える
32

Python 2 と 3 の間に違いはありません。

ソート可能性:

比較方法を定義する必要があります。これにより、アイテムがソート可能になります。一般に、 を好まないでください__cmp__()

私は通常 functools.total_ordering デコレーターを使用します。

functools.total_ordering(cls) 1 つ以上の豊富な比較順序付けメソッドを定義するクラスが与えられた場合、このクラス デコレータは残りを提供します。これにより、可能なすべてのリッチ比較操作を指定する作業が簡素化されます。

クラスは__lt__()__le__()__gt__()、または のいずれかを定義する必要があります__ge__()。さらに、クラスは__eq__()メソッドを提供する必要があります。

比較方法に副作用がないように注意する必要があります。(オブジェクトの値を変更します)

ハッシュの場合:

メソッドを実装する必要があります__hash__()。を返すのが最善の方法だと思うhash(repr(self))ので、ハッシュは一意になります。

于 2011-08-22T19:38:18.817 に答える
4

オブジェクトをソート可能にする方法はいくつかあります。最初 - 一連の関数によって定義されるリッチ比較:

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

また、関数を 1 つだけ定義することもできます。

object.__cmp__(self, other)

__hash__カスタム関数を定義する場合は、最後を定義する必要があります。ドキュメントを参照してください。

于 2011-08-22T19:35:39.270 に答える