Python wieder verwendet den gleichen Speicherplatz wie Sie keine anderen Verweise auf die Objekte halten, sobald id(a.f)
ausgewertet wird mehr Verweise auf das Objekt sind, so dass es gc'd wird dann den gleichen Speicherplatz Python ist frei wiederzuverwenden für a.g
. wenn Sie die Methoden Namen zuweisen werden Sie ein anderes Verhalten sehen:
# creates a reference to the method f
In [190]: f = a.f
# creates a reference to the method g
In [191]: g = a.g
# cannot reuse the memory location of f as it is still referenced
In [192]: id(f) == id(g)
Out[192]: False
Sie eigentlich wirklich nur speichern, müssen Sie einen Verweis auf f wie oben das gleiche Verhalten zu sehen.
In [201]: f = a.f
In [202]: id(f) == id(a.g)
Out[202]: False
können Sie den Referenzzähler sehen mit sys.getrefcount
oder gc.gc.get_referrers
:
In [2]: import gc
In [3]: f = a.f
In [4]: len(gc.get_referrers(a.g)),len(gc.get_referrers(f))
Out[4]: (0, 1)
In [5]: sys.getrefcount(a.g),sys.getrefcount(f)
Out[5]: (1, 2)
Der einzige Grund, warum Sie 1 für ag sehen, weil Die Zahl zurückgegeben wird, ist im Allgemeinen eine höhere als man erwarten könnte, weil es enthält den (temporären) Verweis als Argument für getrefcount(). Es ist analog zu Ihrem eigenen Beispiel, nachdem die Methode ausgewertet wird Sie immer noch einen Verweis auf f
haben, mit a.g
wäre der Refcount 0, so dass es sofort Müll gesammelt und Python ist frei, den Speicherort für alles andere zu verwenden .
Es ist auch erwähnenswert, dass das Verhalten nicht auf Verfahren beschränkt ist, sondern es ist nur ein CPython Implementierungsdetail und nicht etwas, das Sie jemals verlassen sollen:
In [67]: id([]), id([])
Out[67]: (139746946179848, 139746946179848)
In [73]: id(tuple()),id([]),id([])
Out[73]: (139747414818888, 139746946217544, 139746946217544)
In [74]: id([]),id([]),id([])
Out[74]: (139746946182024, 139746946182024, 139746946182024)
In [75]: id([]),id(tuple()),id([])
Out[75]: (139746946186888, 139747414818888, 139746946186888)
In [76]: id(tuple()),id([]),id(tuple())
Out[76]: (139747414818888, 139746946217736, 139747414818888)
Es ist mein Verständnis, das leere Tupel ist ein Singleton (Implementierung Detail). Das ist also für mich nicht so interessant wie das leere Listenbeispiel. –