ホームページ  >  記事  >  バックエンド開発  >  Python の関数内と関数外で、大きな整数に対する「is」演算子の動作が異なるのはなぜですか?

Python の関数内と関数外で、大きな整数に対する「is」演算子の動作が異なるのはなぜですか?

DDD
DDDオリジナル
2024-11-01 15:31:02827ブラウズ

Why does the `is` operator behave differently with large integers inside and outside functions in Python?

関数内の大きな整数に対する演算子の予期しない動作


Python のインタープリタを実験したところ、is に関する興味深い矛盾が発見されました。演算子。

評価が関数内で実行された場合は True が返されますが、外部で実行された場合は結果は False になります。


デフォルトfunc():

a = 1000
b = 1000
return a is b

a = 1000
b = 1000
a は b, func()
>(False, True)

is 演算子はオブジェクトの ID。これは、func 関数内では a と b が同じ整数インスタンスを参照しているのに対し、関数外では別個のオブジェクトを参照していることを示します。

説明

リファレンスマニュアルとして注:


ブロックは、単位として実行される Python プログラム テキストの一部です。
次のブロックがあります: モジュール、関数本体、およびクラス定義。
対話的に入力された各コマンドは、 block.


したがって、関数内では、single コード ブロックは single を保持します。 数値リテラル オブジェクト (1000 など)。id(a) == が True になります。 id(b).

2 番目のインスタンスでは、個別のコード オブジェクト が存在し、それぞれに 1000 の数値リテラルがあり、 id(a) ! が発生します。 = id(b).

重要なのは、これです。この動作は整数リテラルに限定されるものではありません。比較可能な結果は、float リテラルで観察されます (こちらを参照)。

オブジェクトの比較には、等価演算子 (==) を使用することを忘れずに、恒等演算子 (is) は使用しないでください。

この知識は以下に関係しますCPython、Python の主要な実装。代替実装はさまざまな動作を示す可能性があります。

コード分析


理解を助けるために、コードを使用してこの動作を確認してみましょう。物体Analysis.

Function func:

Function オブジェクトには、コンパイルされたバイトコードを明らかにする code 属性があります。 dis.code_info はこのデータを簡潔に示します:

<br>print(dis.code_info(func))<br>名前: func<br>ファイル名: <stdin><br>引数数: 0<br>Kw のみの引数: 0 <br>ローカル数: 2<br>スタック サイズ: 2<br>フラグ: OPTIMIZED、NEWLOCALS、NOFREE<br>定数:<br> 0: なし<br> 1: 1000<br>変数名:<br> 0: a<br> 1: b<br>

定数エントリは、定数が None (常に存在) と 1000 であることを示しています。 したがって、 があります。 1000 を表す 1 つの int インスタンス。a と b はこの 1 つのオブジェクトを参照します。

対話型コマンド:

各コマンドは独立して解析、コンパイル、評価されるコード ブロック:

<br>com1 =compile("a=1000", filename="", mode="single) ")<br>com2 = apply("b=1000", filename="", mode="single")<br>

各割り当てのコード オブジェクト見た目は似ていますが、重要な点、com1 と com2 には 1000 に対して個別の int インスタンスがあり、id(com1.co_consts[0]) == id(com2.co_consts[0]) が False になります。

異なるコード オブジェクト、異なる内容。

注意事項

  • 連鎖ステートメント: a = 1000; を評価しています。 b = 1000 は、これらの連鎖された割り当てが 1 つのコード ブロックにコンパイルされ、1000 のインスタンスが 1 つ生成されるため、真の ID を生成します。

  • モジュール レベル: モジュール レベルでの実行 (リファレンス マニュアルで示されている) も、単一のコード オブジェクトにより True になります。
  • gt;
  • 可変オブジェクト: 同じオブジェクトに明示的に初期化されていない限り、変更可能なオブジェクトの ID チェックは失敗します (例: a = b = [])。

  • 以上がPython の関数内と関数外で、大きな整数に対する「is」演算子の動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。