Python歴もやっと1年くらいになったのですが、今更ながら、比較演算子の is
と、 ==
を明確に区別できてなかったことに気づきました。自分への戒めのために記載。
1. 整理
is
は、Object Identity
==
は、Object Equality
である。
Object Identity はその名の通り、同一のオブジェクトかどうかの判定を行う。
一方、==
については、 __eq__
メソッドと同一の実装であり、
例えば、異なるオブジェクト間でも、文字列が一致するかどうか、などの判定を行う。
https://docs.python.org/3/reference/datamodel.html#object.__eq__
a = 'hoge'
print(a.__eq__('hoge')) # True
2. Usage
a = None
if a == None:
print('Not good')
に対して、PEP8に準拠すると、下記がアラートされる。
E711 comparison to None should be 'if cond is Nond:'
これは、Noneのようなsingletonに対しては、Object Identityでの同一性を比較すべきと言っている。
なので、下記のように書くのが望ましい。
a = None
if a is None:
print('Good')
けれど、Noneであることを特に明示する必要が無い場合は↓のほうがPythonic。
(3. 余談にも書いてます)
a = None
if not a:
print('Good')
また、例えば、下記のように文字列比較に is
を使ってしまうと適切に評価できていないので、
文字列が一致する、といったような比較を行いたい場合には、 ==
を使う必要がある。
(あと、文字列比較の場合には unicode か str かについても、気をつけた方が良い)
a = 'hoghoge'
if a is 'hogehoge':
print('This is not called!')
else:
print('This is called!')
3. 余談
if a:
というif節もPythonではよく使われる。
これは、
if a is not None:
とは異なり、aが、
False
[]
None
''
0
のいずれとも異なる、という意味になる。
明示的にこれらとの比較をした方が良い場合には、
if a is not <比較対象>:
そうでない場合には、
if a:
でOK。
4. まとめ
用法をよく理解して、正しく、Pythonicなコードを書きましょう。