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

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

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

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

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


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

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

<br>def func():<pre class="brush:php;toolbar:false">a = 1000
b = 1000
return a is b

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

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

説明


リファレンス マニュアルの注記:


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


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

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

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

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

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

コード分析


理解を助けるために、コードを使用してこの動作を確認してみましょう。オブジェクト分析。

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 までご連絡ください。