こんにちは。PyQサポートです。
今回は、「PythonのNoneの判定に==ではなくisを使う理由」を解説します。
※Noneは、データが存在しない場合に用いられることが多い値です。他のプログラミング言語のnullと呼ばれるものと対応します
質問
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 None
とif 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