Programmingバックエンド/Python開発者

Pythonにおけるis演算子と==演算子のセマンティクスについて説明してください。両者の違いは何で、どのような場合にそれぞれの使用が重要ですか?典型的な罠の例を挙げてください。

Hintsage AIアシスタントで面接を突破

回答

  • **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になります(オブジェクトが独立しています)。


歴史

例 1

あるマイクロサービスでは、文字列の等価性をisを使用してチェックしました。インタープリタの最適化のおかげで、プログラムはテスト中に「安定して」動作しましたが、再コンパイルや環境の他の変更後に失敗し始めました。


例 2

ある開発者は数字の比較にis演算子を使用しました。小さな数字に対しては機能しました(プールのおかげで)が、大きな数字に対しては失敗し、予測不可能な結果をもたらし、計算の不正確な動作を引き起こしました。


例 3

認証システムの設計では、受信したJSONをis Noneを使ってチェックしました(正しい手法でした)が、その後同様に文字列に対しても行いました:if status is "ok"。これは誤りとなり、条件が時折満たされず、データ処理の論理に誤りをもたらしました。