Python学習チャンネル by PyQ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Noneの判定に==ではなくisを使う理由。同値性と同一性を解説します

f:id:nana_yu:20181206102825p:plain

質問

PyQの問題に、「値がNoneかを判定するには==演算子ではなく、is演算子もしくはis not演算子を利用します。is演算子はisの左右が同一のオブジェクトであるかを比較する演算子です。」 とありました。

ですが、if name == None:としても、プログラムの実行結果は同じでした。

それでも is を使うべき理由は何でしょうか?

回答 同値性と同一性

プログラミングでは同値性同一性という概念があります。

同値性を検査する==

Pythonの==同値かどうか(同値性)を検査します。

これは、「同じ値と見なしてよければTrueとしよう」という考え方です。

見なしてよいか、の部分はPythonのクラス実装でプログラマーがカスタマイズできるので、何を同値と判定するかは対象のオブジェクトによって異なります。 このため、name == Noneだからといって、実際の name の値が None だとは限らないのです(文末に参考コードを添付します)。

同一性を検査するis

Pythonのis同一かどうか(同一性)を検査します。

これは、「完全に同じものだったらTrueにしよう」という考え方です。

これはプログラマーがカスタマイズできないので、name is Noneの結果がTrueなら、 name は None 以外にはありえません。

具体的なif name is Noneif name == Noneの違い

==isの違いを踏まえると、Noneの判定は以下のように考えられます。

if name is Noneと書いてあった場合

「確実に name の値が None である場合」を期待したコード、という事になり、name変数にどんなオブジェクトが割り当てられる可能性があるかを気にする必要はありません。

if name == Noneと書いてあった場合

name がどんなオブジェクトなのかによって動作が異なるため、代入文や関数呼び出し元でどんな値を代入しているか調べないと、どのように動作するか正確なことが言えなくなります。

このような「可能性」を減らすためにis Noneを使うことで、考えたり調査したりする時間を削減し、プログラムのバグを減らせるようになります。

参考コード

>>> class Foo:
...     def __eq__(self, other):  # 同値性検査の動作をカスタマイズ
...         return True
... 
>>> name = Foo()
>>> name == None
True
>>> name is None
False
Copyright ©2017-2019 BeProud Inc. All rights reserved.