2016-12-20 1 views
1

Ich habe ein Wörterbuch nicht entfernen, die als Schlüssel Objektinstanz hat:Löschen ein Objekt als Schlüssel in dict verwendet hat den Korrespondenten Schlüssel in dem dict

outputs = {instance1:instance1.id, instance2:instance2.id} 

Als ich von außerhalb des dict das Objekt löschen, der Korrespondenten Schlüssel wird nicht aus dem Wörterbuch gelöscht, was nicht erwartet wurde.

Was ich erreichen wollte, ist, dass, wenn das Objekt von außerhalb des Diktats gelöscht wird, der Schlüssel auch aus dem Diktat verschwinden.

+0

Was meinen Sie mit dem Löschen des Objekts? Zeigen Sie uns den Code, der nicht funktioniert. – Moberg

+1

Das ist, weil instance1 oder instance2 nicht in einem Wörterbuch referenziert werden, stattdessen wird ihr Hash berechnet und zum Nachschlagen gespeichert. – dnit13

+1

Der Referenzzähler für diese Objekte kann nicht auf Null fallen, weil Sie im Wörterbuch Referenzen auf sie haben. Wenn Sie ein anderes Verhalten benötigen, machen Sie den Schlüssel zu einem [schwachen Verweis] (https://docs.python.org/3/library/weakref.html). – jonrsharpe

Antwort

2

Tatsächlich ist Ihr Objekt in einer Variablen gespeichert und das Objekt, das als Schlüssel im Wörterbuch verwendet wird, stimmt nicht genau überein. Sie sind zwei verschiedene Referenzen auf das gleiche Objekt im Speicher.

ist das folgende Beispiel nehmen lassen:

class Foo(object): 

    def __init__(self, _repr): 
     self._repr = _repr 

    def __repr__(self): 
     return '{}-{}'.format(self._repr, id(self)) 

a = Foo('f1') 
# The count returned by getrefcount() is generally one higher than you might expect, because it includes the (temporary) reference as an argument to getrefcount() 
print(sys.getrefcount(a) - 1) # Out: 1 
d = {a: 'value'} # Out {f1-139822435732560: 'value'} 
print(sys.getrefcount(a) - 1) # Out: 2 
a._repr = 'f2' 
print(d) # Out {f2-139822435732560: 'value'} 

, die das dict erstellt einen neuen Verweis auf das Hauptobjekt prouves. Und weil Python wichtigste Methode der Speicherverwaltung Referenzzählung verwendet:

Python hält eine Zählung aller Verweise auf das Objekt, und wenn es keine mehr übrig sind, wird das Objekt gelöscht.

so, wenn Sie die Referenz in dem del a varaiable gespeichert löschen, die Referenz in der dict gespeichert war.

del a 
print(sys.getrefcount(d.keys()[0]) - 1) # Out: 1 

Und das wird Unbeständigkeit machen in Sie dict, weil Sie mehr Zugriff auf Ihre Daten haben, empfehle ich die variable Referenz zu verwenden, um die Daten aus dem dict löschen als das Objekt löschen.

del d[a] 
print(sys.getrefcount(a) - 1) # Out: 1 
del a 
1

Bevor Sie das Objekt löschen, müssen Sie den Schlüssel aus dem Wörterbuch löschen.

Dies passiert, weil das dict nicht das Objekt als Schlüssel speichert, sondern einen Hash, der daraus generiert wird.

Verwandte Themen