1. ホーム
  2. パイソン

[解決済み】オブジェクトのインスタンスを属性で比較し、同等性を確認する

2022-03-30 23:23:54

質問

私はクラス MyClass この変数には2つのメンバ変数が含まれています。 foobar :

class MyClass:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

このクラスのインスタンスが2つあり、それぞれのインスタンスの foobar :

x = MyClass('foo', 'bar')
y = MyClass('foo', 'bar')

しかし、これらを等しいかどうか比較すると、Python は False :

>>> x == y
False

pythonにこの2つのオブジェクトを等しいと思わせるにはどうしたらいいですか?

どのように解決するのですか?

メソッドを実装する必要があります。 __eq__ :

class MyClass:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar
        
    def __eq__(self, other): 
        if not isinstance(other, MyClass):
            # don't attempt to compare against unrelated types
            return NotImplemented

        return self.foo == other.foo and self.bar == other.bar

これで出力されるようになりました。

>>> x == y
True

を実装することに注意してください。 __eq__ を使用すると、クラスのインスタンスは自動的にハッシュ化できなくなり、 セットやディクテに格納することができなくなります。もしあなたが不変の型をモデル化していないなら(すなわち foobar がオブジェクトのライフタイム内に値を変更する可能性がある場合)、インスタンスをハッシュ化できないままにすることを推奨します。

immutable 型をモデル化する場合は、データモデルフックも実装する必要があります。 __hash__ :

class MyClass:
    ...

    def __hash__(self):
        # necessary for instances to behave sanely in dicts and sets.
        return hash((self.foo, self.bar))

をループさせるというような一般的な解決策。 __dict__ と値を比較することはお勧めできません。 __dict__ には、比較できない型やハッシュ化できない型が含まれている可能性があります。

注:Python 3 より前のバージョンでは、Python 3 で使用するために __cmp__ の代わりに __eq__ . Python 2 のユーザは __ne__ なぜなら、不等号のための賢明なデフォルト動作(すなわち、等号の結果を反転する)は、Python 2では自動的に作成されないからです。