is**はオブジェクトの同一性を比較します(つまり、変数が同じメモリ領域を指しているかどうか)。==(operator eq)は値を比較します。つまり、オブジェクトの内容に関して等しいかどうかを判断します。**is**は特に同一性(例えば、Noneやシングルトンオブジェクトの場合)を比較するために使用すべきであり、値の等しさを検証するためには使用しないでください。
例:
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True
小さな整数や文字列を扱う場合、インタープリタが「インターニング」(キャッシュされたオブジェクト)を利用する場合があり、これによって等しい値に対してisが真になることがありますが、これはプログラムの論理には使用すべきではありません。
質問: 次のコードは何を出力しますか?
a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)なぜですか?
回答:
-5から256までの値について、Pythonは整数プールを使用しています。この範囲内の値は常に同じオブジェクトを指すため、a is bはTrueを返します。しかし、257はプールの外にあるため、c is dはFalseになります(オブジェクトが独立しています)。
歴史
あるマイクロサービスでは、文字列の等価性をisを使用してチェックしました。インタープリタの最適化のおかげで、プログラムはテスト中に「安定して」動作しましたが、再コンパイルや環境の他の変更後に失敗し始めました。
ある開発者は数字の比較にis演算子を使用しました。小さな数字に対しては機能しました(プールのおかげで)が、大きな数字に対しては失敗し、予測不可能な結果をもたらし、計算の不正確な動作を引き起こしました。
認証システムの設計では、受信したJSONをis Noneを使ってチェックしました(正しい手法でした)が、その後同様に文字列に対しても行いました:if status is "ok"。これは誤りとなり、条件が時折満たされず、データ処理の論理に誤りをもたらしました。