pythonのisと==の違いを知りました
はじめに
本記事で扱うこと
- python における同一性
- python の is の意味
- python の==の意味
- オブジェクトの比較
あらまし
python でコードを書いているとき、辞書ならびにオブジェクトを比較したい事案が発生しました。
そのため、以下のようなコードを書いて振る舞いを確認してみました。
私が思っていた挙動としては a == b
が False
となることでしたが、予想に反して値が一緒であれば True
になるようです。
細かい挙動について気になったため、==と is について調べることにしました。
a = {'x': 10, 'y': 20, 'z': {'a': 0, 'b': ['u']}}
b = {'x': 10, 'y': 20, 'z': {'a': 0, 'b': ['u']}}
print(a == b)
print(a is b)
print(id(a))
print(id(b))
"""
True
False
4543310848
4543656768
"""
pythonにおける同一性
python はすべてオブジェクトで表現されています。
このオブジェクトとはデータを抽象的に表したものです。
このとき、オブジェクトには 同一性
というものが設定されており、生成されたあとは変更されていません。
つまり、あるオブジェクトが必ずそのオブジェクト自身であることを保証・証明するものと考えることができます。
オブジェクトの同一性は id
関数で確認できます。
pythonにおけるis
python の is
は、同一性を検証します。
つまり、完全に同じオブジェクトであるかを is 関数を用いて比較します。
よって、最初のコード例では a is b
と id(a) == id(b)
は同じであり、同一性を検証します。
pythonにおける==
==
演算子は、値自体を比較します。
そのため、同一性の比較ではありません。
実現方法として、__eq__
というオブジェクトの特殊メソッドを ==
が実行時に呼び出すことで実現しています。
例えば、以下のように __eq__
を実装するとプロパティである x の絶対値が 1 以下であれば、値が等しい
というクラスを定義できます。(実際にこういうのを使うかどうかは無視してください...)
from __future__ import annotations
class A:
def __init__(self, x: int):
self.x = x
def __eq__(self, other: A):
return abs(self.x - other.x) <= 1
v = A(x=0)
w = A(x=1)
print(v == w)
print(v is w)
"""
True
False
"""
オブジェクトの比較
python のオブジェクトの比較は、再帰的に 値が等しいか
をチェックしています。
そのため、id
の同一性ではなく実値自体を比較しています。
値を比較したいなら ==
を、真の意味で同じオブジェクトが調べるときは is
を使うようにしようと思います。
Discussion