[Python] classを比較する方法とinの挙動メモ

Python 5月 14, 2016

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演算子に関しては、結果を見て分かる通り、==演算子**の結果に依存するようです。つまり、同値性の判定結果を返しているのでしょう。


同一性や同値性といったこれらの性質は、プログラミングにおいて非常に大事なので、どんな言語でも常に把握しておきたいですね。

slont

金融ベンチャーでWebエンジニア。美と酒とTechで生きてる。Vue.jsが至高。Elixir好き。個人事業とWebアプリ案件もやってます。 アプリ→https://app.cullet.me Android→https://play.google.com/store/apps/details?id=net.maytry.cullet.android

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.