Python では、カスタム クラスは __eq__ メソッドと __ne__ メソッドを実装して == 演算子と != 演算子の等価性を定義できます。それぞれ。ディクショナリ属性を比較する従来の方法は簡単ですが、一定の制限があります。
次のシナリオを検討してください:
class Number: def __init__(self, number): self.number = number n1 = Number(1) n2 = Number(1) # Default comparison fails: they are different objects assert n1 != n2
この問題に対処するには__eq__ メソッドをオーバーライドできます:
class Number: def __init__(self, number): self.number = number def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return False
ただし、Python 2 では、次のようにすることもできます。可換動作を保証するには __ne__ を実装する必要があります:
class Number: def __init__(self, number): self.number = number def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return False def __ne__(self, other): return not self.__eq__(other)
これにより、n1 == n2 が期待どおり True に評価されることが保証されます。
サブクラスの導入により等価性が複雑になります比較:
class SubNumber(Number): pass n3 = SubNumber(1) # Subclass comparison fails for classic-style classes assert n1 == n3 # False (for classic-style classes) assert n3 == n1 # True # Non-commutative comparison assert n1 != n3 # True (for classic-style classes) assert n3 != n1 # False
の場合クラシック スタイルのクラスでは、最初のオペランドの型に基づいて比較メソッドが呼び出され、非可換動作が発生します。これに対処するために、サポートされていないオペランド型に対して NotImplemented を返すことができます。これにより、比較が他のオペランドのメソッドに委任されます。
def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return NotImplemented
最後に、set はオブジェクト識別子を使用することに注意してください。ハッシュ化により、誤った結果が生じる可能性があります:
assert len(set([n1, n2, n3])) == 3 # Incorrectly reports 3 unique numbers
これを解決するには、 __hash__ メソッドをオーバーライドできます:
def __hash__(self): return hash(tuple(sorted(self.__dict__.items())))
これらの機能強化により、等価性と一意性の動作が正しく一貫性を持ち、堅牢な比較とセットでの正確な表現が保証されます:
assert len(set([n1, n2, n3])) == 1 assert len(set([n1, n2, n3, n4])) == 2
以上が特にサブクラスやセットを扱う場合、カスタム Python クラスの一貫性と堅牢な等価性比較をどのようにして確保しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。