ホームページ  >  記事  >  バックエンド開発  >  特にサブクラスやセットを扱う場合、カスタム Python クラスの一貫性と堅牢な等価性比較をどのようにして確保しますか?

特にサブクラスやセットを扱う場合、カスタム Python クラスの一貫性と堅牢な等価性比較をどのようにして確保しますか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-11-09 04:50:02358ブラウズ

How do you ensure consistent and robust equivalence comparisons for custom Python classes, especially when dealing with subclasses and sets?

Python クラスでの等価比較のためのエレガントなアプローチ

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

Hashing と Sets

最後に、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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。