2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonにおけるオブジェクトの同値判定

Last updated at Posted at 2016-07-24

目的

pythonにおいてオブジェクトの同値判定の仕組みを知った上で自分で定義した同値判定を利用できるようにする
obj1 == obj2 および obj1!=obj2での判定の仕組みについて

環境

python : 3.5.1, 2.7.10

pythonの組み込み関数での同値判定

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

上記の通り、Fooクラスを定義した上で以下のようにfoo1とfoo2のインスタンスを作成して、
同値判定やリストの存在の有無の判定を行うと、同じインスタンスではTrueになるが、メンバ変数の値が同じでインスタンスが異なる場合はFalseになる。

  foo1 = Foo("foo", 24)
  foo2 = Foo("foo", 24)
  print(foo1 == foo1) # -> True
  print(foo1 == foo2) # -> False
  print(foo1 in [ foo1 ]) # -> True
  print(foo1 in [ foo2 ]) # -> False
  print(foo1 != foo1) # -> False
  print(foo1 != foo2) #-> True

自作する場合

pythonの==obj in objlistで同値判定を行う際には、
obj.__eq__メソッドが呼び出される
一方、!=には、obj.__ne__が 呼び出される
ただし、obj.__eq__を定義すれば、3.5.1(3系全部?)ではobj.__ne__はその逆を返してくれるのでobj.__eq__のみをオーバライドすればよい
2.7.10では、__ne__も定義してあげないと、obj.__ne__の結果はオーバライドしたobj.__eq__の逆の値を返してくれない
2系と3系で統一したい場合は、__ne__を定義しておくことをお勧めします。

ただし、__eq__のときはまず始めに比較対象が同じクラスかどうかの判定するメソッドisinstance(obj, CLASSNAME)を呼び出さないといけないことに注意
メンバ変数のnameageが同じであれば、同じとみなす場合、以下のように定義する

class Bar(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __eq__(self, obj):
        if isinstance(obj, Bar):
            return self.name == obj.name and self.age == obj.age
        else:
            return False

    # 2.7.10(おそらく2.7系全部)では以下も必要
    def __ne__(self, obj):
        return not self.__eq__(obj)

上記のようにBarクラスを定義し、bar1, bar2, bar3 のインスタンスを以下のように作成して同値判定等の結果を見ると次のようになる

bar1 = Bar("bar", 24)
bar2 = Bar("bar", 24)
bar3 = Bar("foo", 24)

print(bar1 == bar1) # -> True
print(bar1 == bar2) # -> True
print(bar1 == bar3) # -> False

print(bar1 in [ bar1 ]) # -> True
print(bar2 in [ bar1 ]) # -> True
print(bar3 in [ bar1 ]) # -> False

print(bar1 != bar1) # -> False
print(bar1 != bar2) # -> False 2.7.10では__ne__を定義してないとTrueになる
print(bar1 != bar3) # -> True
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?