Nach dem Lesen von this und < a href="https://stackoverflow.com/questions/31152195/python-multiple-assignment-and-references/31153595"> dies , die meiner Frage ziemlich ähnlich sind, kann ich das folgende Verhalten immer noch nicht verstehen :
%Vor% Beim Drucken von id(a)
und id(b)
kann ich sehen, dass die Variablen, denen die Werte in separaten Zeilen zugewiesen wurden, unterschiedliche IDs haben, während bei mehrfacher Zuweisung beide Werte die gleiche ID haben:
Aber es ist unmöglich, dieses Verhalten zu erklären, indem man sagt, dass mehrfache Zuweisung derselben Werte immer Zeiger auf die gleiche ID erzeugt, seit:
%Vor% Gibt es eine klare Regel, die erklärt, wann die Variablen die gleiche id
bekommen und wann nicht?
Bearbeiten
relevante Info: Der Code in dieser Frage wurde im interaktiven Modus (ipython3)
ausgeführtDies liegt an einer konstanten Faltungsoptimierung im Bytecode-Compiler. Wenn der Bytecode-Compiler einen Stapel von Anweisungen kompiliert, verwendet ein Diktat , um es zu behalten Spur der Konstanten, die es gesehen hat. Dieses Diktat führt automatisch äquivalente Konstanten zusammen.
Hier ist die Routine, die für die Aufzeichnung und Nummerierung von Konstanten zuständig ist (sowie einige damit verbundene Verantwortlichkeiten):
%Vor% Sie können sehen, dass nur ein neuer Eintrag hinzugefügt und eine neue Nummer zugewiesen wird, wenn keine äquivalente Konstante bereits vorhanden ist. (Das Bit _PyCode_ConstantKey
stellt sicher, dass Dinge wie 0.0
, -0.0
und 0
als nicht gleichwertig betrachtet werden.)
Im interaktiven Modus endet eine Stapelverarbeitung jedes Mal, wenn der Interpreter den Befehl tatsächlich ausführen muss. Daher findet die konstante Faltung meistens nicht über Befehle statt:
%Vor%In einem Skript sind alle Anweisungen auf oberster Ebene ein Stapel, sodass konstanteres Falten auftritt :
%Vor% In einem Skript wird True
gedruckt.
Der Code einer Funktion erhält ihre Konstanten getrennt von Code außerhalb der Funktion, der die konstante Faltung begrenzt:
%Vor% Auch in einem Skript wird False
gedruckt.
Das liegt an der Optimierung des Python-Interpreters bei UNPACK_SEQUENCE
time, beim Laden der const-Werte. Wenn Python während des Entpackens auf eine iterierbare Zahl trifft, lädt es die doppelten Objekte nicht mehrfach, sondern behält nur das erste Objekt und weist alle Ihre Namen einer Objektadresse zu. Daher wären alle Ihre Variablen die gleichen Referenzen auf ein Objekt.
Eigentlich entspricht Ihr Entpacken dem folgenden Befehl:
%Vor%Und über die negativen Zahlen in Python 2.X macht es keinen Unterschied, aber in Python 3.X scheint es, dass für Zahlen kleiner als -5 Python beim Entpacken ein neues Objekt erzeugt:
%Vor%Tags und Links python python-3.x multiple-assignment