Verschiedene Klasseninstanzen verwenden denselben Speicherplatz

Ich spielte mit der pickle Bibliothek herum, als ich bemerkte, dass manchmal verschiedene Klasseninstanzen am selben Speicherplatz sind.

Beide der folgenden Beispiele zeigen das Verhalten:

 class DemoClass: def __init__(self): self.name = 'demoName' #example 1 for i in range(3): print (DemoClass()) #example 2 [print(DemoClass()) for i in range(3)] #Output for both example 1 and example 2 #Note that the memory locations are identical in the output <__main__.DemoClass object at 0x00CEE610> <__main__.DemoClass object at 0x00CEE610> <__main__.DemoClass object at 0x00CEE610> 

Das war ziemlich überraschend für mich, also vielleicht könntest du dir erklären, warum dies geschieht

Die Art und Weise, in der das Programm fungiert, wie ich es erwarten würde, ist wie folgt.

 demo = [DemoClass() for i in range(3)] for i in demo: print (i) #Output <__main__.DemoClass object at 0x01F7E630> <__main__.DemoClass object at 0x01F7ED30> <__main__.DemoClass object at 0x01F7E670> 

3 Solutions collect form web for “Verschiedene Klasseninstanzen verwenden denselben Speicherplatz”

Ihre Frage betrifft, wie Python Speicher speichert. Tldr; Python verwendet einen Haufen, um Speicher zu speichern. Wenn eine Ressource befreit ist, geht es an die Spitze des Haufens.

Detaillierte Antwort

Python muss Speicher reservieren, um eine Instanz eines Objekts zu erstellen. Für die Speicher-Effizienz verfügt der Python-Speicher-Manager über einen Haufen von Speicherplätzen, die zur Verfügung stehen oder für die Instanziierung von Objekten reservieren. Mit einigen Ihrer Beispiele können Sie sehen, wie das in der Praxis funktioniert.

Beispiel 1

 >>> for i in range(3): ... print DemoClass() ... <test.DemoClass instance at 0x288b248> <test.DemoClass instance at 0x288b248> <test.DemoClass instance at 0x288b248> 

Während der ersten Iteration der for Schleife verwendet python die erste verfügbare Adresse in ihrem aktuellen Heap, nämlich <0x288b248> , um eine Instanz von DemoClass für den print Aufruf zu erstellen. Sobald der print beendet ist, wird die Speicheradresse freigegeben und kehrt zum Anfang des Heaps zurück . Während der nächsten Iteration der Schleife verwendet python die erste verfügbare Speicheradresse, die wiederum die Adresse <0x288b248> . Etc.

Beispiel # 2

 >>> for j in [DemoClass() for i in range(3)]: ... print j ... <test.DemoClass instance at 0x288bcf8> <test.DemoClass instance at 0x288b290> <test.DemoClass instance at 0x288b638> 

Hier erzeugt python eine Liste, die es dann durchlaufen wird. Die Erstellung der Liste erfordert, dass für jedes Element eine neue Instanz von DemoClass erstellt wird. Dies wird die ersten drei Adressen aus dem Haufen nehmen. Nachdem die Schleife fertig ist, wird die Liste vom Speicher befreit und wenn wir wieder einen Aufruf zum print(DemoClass) wir feststellen, dass die print(DemoClass) wieder Speicher ist.

 >>> print DemoClass() <test.DemoClass instance at 0x288bcf8> 

Beispiel 3 (Mein Beispiel für die Wechselspeicherzuordnung)

 >>> for i in xrange(4): ... Demo = DemoClass() ... print(Demo) ... <test.DemoClass instance at 0x288bcf8> <test.DemoClass instance at 0x288b290> <test.DemoClass instance at 0x288bcf8> <test.DemoClass instance at 0x288b290> 

In diesem Beispiel wird jedes Mal, wenn Demo als Instanz von DemoClass instanziiert wird, dem Speicher eine Speichereinheit zugeordnet. Der Aufruf zum print(Demo) befreit jedoch nicht den dem Demo zugeordneten Speicher. Am Anfang der nächsten Schleife wird ein neues Segment des Speichers dem Demo zugewiesen und dann wird Demo überschrieben , an welcher Stelle die ursprüngliche Speicheradresse an die Spitze des Heaps zurückkehrt. Die für Demo verwendete Speicheradresse wechselt dann zwischen zwei Speicheradressen.

In den ersten 2 Beispielen, sobald der Aufruf zum print beendet ist, hat das Objekt keine Referenz mehr und kann daher beim nächsten Erstellen des Objekttyps wieder verwendet werden.

Im zweiten Fall haben alle Instanzen gleichzeitig Referenzen und müssen daher deutlich sein.

Ich würde mich aber nicht auf dieses Verhalten verlassen, denn zum Beispiel könnte es noch andere, nicht referenzierte Instanzen dieses Objekts geben.

Wenn ein Objekt nicht mehr existiert, steht sein Standort sofort zur Wiederverwendung zur Verfügung.
Da Python-Objekte Referenzzählungen sind, verschwinden sie, sobald sich nichts auf sie bezieht.

Wenn die Dinge so funktionieren, wie du es erwartest, könntest du ziemlich schnell aus dem Gedächtnis herauskommen.

Python ist die beste Programmiersprache der Welt.