Sie haben id()
falsch verwendet. id([])
übernimmt die Speicher-ID eines Objekts, das sofort verworfen wird. Immerhin referenziert nichts mehr, wenn fertig ist. Also das nächste Mal, wenn Sie id([])
verwenden Python sieht eine Gelegenheit, den Speicher wieder zu verwenden und siehe da, diese Adressen sind in der Tat gleich.
Dies ist jedoch ein Implementierungsdetail, auf das Sie sich nicht verlassen können, und es wird nicht immer in der Lage sein, die Speicheradresse wiederzuverwenden.
Beachten Sie, dass id()
Werte für die Lebensdauer des Objekts nur einzigartig sind, sehen die documentation:
Dies ist eine ganze Zahl, die für dieses Objekt eindeutig und konstant ist während seiner gesamten Lebensdauer gewährleistet ist. Zwei Objekte mit nicht überlappenden Lebensdauern können den gleichen Wert haben id()
.
(Fett Hervorhebung meins).
id(list())
kann den Speicherort nicht wiederverwendet werden, wahrscheinlich aufgrund der zusätzlichen Heap-Mutationen verursacht durch Drücken des aktuellen Rahmens auf dem Stapel, um eine Funktion aufzurufen, dann erneut, wenn der list()
Aufruf zurückgibt.
Beide und list()
produzieren ein neues leeres Listenobjekt; aber Sie müssen zuerst Verweise auf diese separate Listen erstellen (hier a
und b
):
>>> a, b = [], []
>>> a is b
False
>>> id(a) == id(b)
False
>>> a, b = list(), list()
>>> a is b
False
>>> id(a) == id(b)
False
Das gleiche passiert, wenn Sie [].__repr__
verwendet. Das interaktive Python-Interpreter hat einen speziellen globalen Namen, _
, dass Sie das letzte Ergebnis erzeugte Referenz verwenden können:
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>
, dass eine zusätzliche Referenz erzeugt, so dass die __repr__
Verfahren, und durch die Erweiterung, die leere Liste, die Sie erstellt dafür werden immer noch als aktiv betrachtet. Der Speicherort ist nicht freigegeben und nicht verfügbar für die nächste Liste, die Sie erstellen.
Bei der erneuten Ausführung von [].__repr__
bindet Python nun _
an das neue Methodenobjekt. Plötzlich wird die vorherige __repr__
-Methode von nichts mehr referenziert und kann ebenso wie das Listenobjekt freigegeben werden.
Das dritte Mal, wenn Sie [].__repr__
den ersten Speicherplatz auszuführen ist wieder verfügbar für die Wiederverwendung, so Python macht genau das:
>>> [].__repr__ # create a new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> _ # now _ points to the new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> [].__repr__ # so the old address can be reused
<method-wrapper '__repr__' of list object at 0x10e011608>
Sie nie mehr als zwei Listen erstellen; der vorherige (immer noch von _
referenziert) und der aktuelle. Wenn Sie mehr Speicherorte anzeigen möchten, verwenden Sie Variablen, um eine weitere Referenz hinzuzufügen.