Python

Pythonにおけるisと==の違い

Pythonの比較演算子isと==の違いを正確に理解していなかったので自分なりにまとめました.

Prerequisite

  • Python 3.6.4

Pythonにおけるisと==の違い

比較演算子is==の違いは以下:

  • isは二つのオブジェクトがオブジェクトとして同一かどうかを判定
  • ==は二つのオブジェクトの値が同じかどうかを判定

Pythonにおける比較演算子is

次のように,Pythonのオブジェクトは作成されると一意に定まるidが付与されます:

>>> a = 10
>>> id(a)
4564182080

このidが同一かどうかを比較演算子isで調べることができます:

>>> a = 10
>>> id(a)
4564182080
>>> b = 10
>>> id(b)
4564182080
>>> a is b
True

上の例の場合では,変数abには整数オブジェクト10への参照が格納されているのでオブジェクトとして同一のものとなります.

次の例では値は同じですが,オブジェクトとしては異なるためisで比較するとFalseとなります:

>>> list1 = [1, 2]
>>> list2 = [1, 2]
>>> id(list1)
4569228232
>>> id(list2)
4569228296
>>> list1 == list2
True
>>> list1 is list2
False

整数の場合とは異なり,配列の場合は毎回オブジェクトが作成されるため同じ値の配列でもそのidは異なるものになります.

比較演算子isの使い所

isの使い所としては,オブジェクトがNoneかどうかを調べるのによく使われます.例えば,以下のように書くことでhogeがNoneであった時にhoge is Noneをprintするようにできます:

hoge = None

if hoge is None:
    print('hoge is None')

Pythonにおける比較演算子==

==は上の例でもあるように二つのオブジェクトの値が同じかどうかを判定します.しかし,==は実際はクラスの__eq__メソッドでの評価となっており,クラスの実装次第では値が同じかどうかを判定しているとは限らないケースがあります.この辺りは実装者がどう実装するかに依存してしまいます.

例えば,次のように__eq__を実装すると,全てのオブジェクトに対して==Falseを返すようになります:

>>> class not_eq:
...     def __init__(self, x):
...             self.x = x
...     def __eq__(self, y):
...             return False
...
>>> a = not_eq(10)
>>> a.x
10
>>> b = not_eq(10)
>>> b.x
10
>>> a == b
False

参考