Python3 Mehrfachzuweisung und Speicheradresse [duplizieren]

9

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:

%Vor%

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ührt     
istern 08.02.2016, 16:56
quelle

3 Antworten

2

Dies 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.

    
user2357112 08.02.2016, 17:53
quelle
2

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%     
Kasramvd 08.02.2016 17:12
quelle
0

Eine solche Regel ist implementierungsspezifisch. Beispielsweise weist CPython int -Objekten für kleine ganze Zahlen (-5 bis 256) als Leistungsoptimierung vor.

Die einzige allgemeine Regel besagt, dass die Verwendung eines Literals ein neues Objekt erzeugt.

    
chepner 08.02.2016 17:10
quelle