[Python] classを比較する方法とinの挙動メモ
pythonでclass同士の比較をする時に気をつけるメモ。
とりあえずソース。
# -*- coding:utf-8 -*-
class Test1(object):
def __init__(self):
'''class初期化'''
self.val = 10
class Test2(object):
def __init__(self):
'''class初期化'''
self.val = 10
def __eq__(self, other):
'''== のオーバーライド'''
return self.val == other.val
def __ne__(self, other):
'''!= のオーバーライド'''
return not self.__eq__(other)
if __name__ == '__main__':
# 2つのTest1インスタンスを作成
test11 = Test1()
test12 = Test1()
# 2つのTest2インスタンスを作成
test21 = Test2()
test22 = Test2()
print '"==" での比較'
print ' test11 == test11 ->', test11 == test11
print ' test11 == test12 ->', test11 == test12
print ' test21 == test22 ->', test21 == test22
print ' [1] == [1] ->', [1] == [1]
print '"is" での比較'
print ' test11 is test11 ->', test11 is test11
print ' test11 is test12 ->', test11 is test12
print ' test21 is test22 ->', test21 is test22
print ' [1] is [1] ->', [1] is [1]
print '"in" でのリスト内に要素があるかどうか判定'
print ' test11 is test11 ->', test11 in [test11]
print ' test11 is test12 ->', test11 in [test12]
print ' test21 is test22 ->', test21 in [test22]
Test1はただのクラスですが、Test2では==
演算子と!=
演算子をオーバーライドしています。そして、それぞれのインスタンスを2つずつ作って、比較しています。
実行結果は以下です。
"==" での比較
test11 == test11 -> True
test11 == test12 -> False
test21 == test22 -> True
[1] == [1] -> True
"is" での比較
test11 is test11 -> True
test11 is test12 -> False
test21 is test22 -> False
[1] is [1] -> False
"in" でのリスト内に要素があるかどうか判定
test11 is test11 -> True
test11 is test12 -> False
test21 is test22 -> True
とてもわかりやすいですね。
pythonでは**==
演算子は同値性の判定に用いられるようです。インスタンスが違っていても、内容が同じであればTrueを返します。これらはclassにおいて、どの値をどのように比較するかを明示的に示してあげなければなりません。
一方、is
演算子は同一性の判定に用いられます。内容が合っていても、インスタンスが違えばFalseになります。Noneはpythonにおいてただ一つのインスタンスを持つオブジェクト(staticオブジェクトみたいなもの?)なので、後者のis
演算子で比較することが推奨されているようです。
また、in
演算子に関しては、結果を見て分かる通り、==
演算子**の結果に依存するようです。つまり、同値性の判定結果を返しているのでしょう。
同一性や同値性といったこれらの性質は、プログラミングにおいて非常に大事なので、どんな言語でも常に把握しておきたいですね。