Beim Experimentieren mit Pythons Interpreter wurde eine merkwürdige Diskrepanz bezüglich des is entdeckt Operator.
Wenn die Auswertung innerhalb einer Funktion durchgeführt wird, gibt sie True zurück, aber wenn sie extern durchgeführt wird, ist das Ergebnis False.
<br>def func():</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">a = 1000 b = 1000 return a is b
a = 1000
b = 1000
a is b, func()
>(False, True)
Da der is-Operator beurteilt Die IDs des Objekts. Dies zeigt an, dass sich a und b innerhalb der Funktion func auf dieselbe ganzzahlige Instanz beziehen, während außerhalb der Funktion Sie beziehen sich auf verschiedene Objekte.
Wie im Referenzhandbuch vermerkt:
Ein Block ist ein Teil des Python-Programmtextes, der als ausgeführt wird eine Einheit.
Die folgenden Blöcke sind: ein Modul, ein Funktionskörper und eine Klassendefinition.
Jeder interaktiv eingegebene Befehl ist ein Block.
< /blockquote>In einer Funktion also ein Single Der Codeblock enthält ein einzelnes numerisches Literalobjekt, z. B. 1000, was zu True für id(a) == id(b) führt.
In Im zweiten Fall sind separate Codeobjekte vorhanden, jedes mit seinem numerischen Literal für 1000, was verursacht id(a) != id(b).
Wichtig ist, dass dieses Verhalten nicht nur auf ganzzahlige Literale beschränkt ist; Vergleichbare Ergebnisse werden mit Float-Literalen beobachtet (siehe hier).
Denken Sie daran, den Gleichheitsoperator (==) zum Vergleichen von Objekten zu verwenden, niemals den Identitätsoperator (is).
Dieses Wissen bezieht sich auf CPython, die primäre Implementierung von Python. Alternative Implementierungen können ein unterschiedliches Verhalten aufweisen.
Codeanalyse
Zum besseren Verständnis überprüfen wir dieses Verhalten mithilfe von Code Objektanalyse.
Funktion func:
Funktionsobjekte haben ein code-Attribut, das den kompilierten Bytecode offenlegt. dis.code_info stellt diese Daten prägnant dar:
<br>print(dis.code_info(func))<br>Name: func<br>Dateiname: <stdin><br>Argumentanzahl: 0<br>Nur-KW-Argumente: 0 <br>Anzahl der Einheimischen: 2<br>Stapelgröße: 2<br>Flags: OPTIMIZED, NEWLOCALS, NOFREE<br>Konstanten:<br> 0: Keine<br> 1: 1000<br>Variablennamen:<br> 0: a<br> 1: b<br>Der Konstanteneintrag zeigt, dass die Konstanten None (immer vorhanden) und 1000 sind. Es gibt also eine int-Instanz, die 1000 darstellt. a und b verweisen auf dieses eine Objekt.
Interaktive Befehle:
Jeder Befehl ist ein Codeblock, der unabhängig analysiert, kompiliert und ausgewertet wird:
<br>com1 = compile("a=1000", filename="", mode="single ")<br>com2 = compile("b=1000", filename="", mode="single")<br>Das Codeobjekt für jede Zuweisung sieht ähnlich aus, aber entscheidend, com1 und com2 haben separate int-Instanzen für 1000, was zu False für id(com1.co_consts[0]) == id(com2.co_consts[0]) führt. p>
Unterschiedliche Codeobjekte, unterschiedliche Inhalte.
Vorbehalte
Verkettete Anweisungen: Auswertung von a = 1000; b = 1000 ergibt True Identität, da diese verketteten Zuweisungen in einem Codeblock kompiliert werden und eine Instanz von 1000 erzeugen.
Modulebene : Die Ausführung auf Modulebene (im Referenzhandbuch angegeben) ergibt aufgrund eines einzelnen Codeobjekts ebenfalls „True“.
Veränderliche Objekte: Identitätsprüfungen schlagen für veränderbare Objekte fehl, es sei denn, sie werden explizit auf dasselbe Objekt initialisiert (z. B. a = b = []).
Das obige ist der detaillierte Inhalt vonWarum verhält sich der „is'-Operator bei großen Ganzzahlen innerhalb und außerhalb von Funktionen in Python unterschiedlich?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!