私がここで見ている問題は、あなたが平等の2つの異なる概念で働いているということです。私があなたのコメントを正しく理解している場合、あなたは2つの引数を組み合わせた式__eq__
を返すようにオーバーライドしました。上記の式が(ある意味で)Trueと評価された場合、2つの式は等しくなります。また、式クラスが( Python 3で)式がtrueの場合に返されるように実装されている場合、表面的にはこれは正常に機能するはずです。==
__nonzero__
__bool__
__nonzero__
True
しかし実際には、あなたが定義した平等の概念は、Pythonで機能している通常の平等の概念とは非常に異なる概念であるように思われます。ハッシュ可能性の基本的な要件は、2つのアイテムが等しいと評価された場合、それらは完全に交換可能である必要があるということです。また、2つの式オブジェクトが「等しい」と評価される場合もありますが、それらが交換可能かどうかはわかりません。結局のところ、同じ結果に評価されますが、それらは同一ではありませ5 + 5
んか?そして、これらの2つの式を考えると、多くの人が辞書内の2つの別々のビンにハッシュすることを期待していると思います。8 + 2
__eq__
ただし、より一般的な定義を与えなければ、その動作は困難です。そして、ドキュメントが言うように、「等しいと比較するハッシュ可能なオブジェクトは、同じハッシュ値を持たなければなりません。」したがって、とが等しいと__eq__
言う場合、それらは同じ値にハッシュする必要があります。つまり、式を現在のようにハッシュ可能にするには、等しいと評価されるすべての式の標準形を決定できるを選択する必要があります。それは私にはひどく難しいように聞こえます。5 + 5
8 + 2
__hash__
つまり、これらの式が不変であり、式が同一である__eq__
場合に戻るように再定義する場合(「等しい」よりも強い要件)、ハッシュ可能にするのに問題はありません。一方、ハッシュ不可能な不変型には何の問題もありません。また、を再定義せずに式をハッシュ可能にしようとすることはお勧めしません。True
__eq__
__eq__
つまり、すべては、型にはまらない方法でどれだけひどく定義したいかにかかっています。バランスをとると、__eq__
予期しない動作が発生しないようにするために、従来の定義を使用すると思います。結局のところ、特別な場合は規則を破るほど特別ではありません。