2016-12-20 7 views
1

У меня есть словарь, который имеет экземпляра объекта в качестве ключей:Удаления объекта, используемый в качестве ключа в Словаре не вынимайте ключ корреспондента в Словаре

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

При удалении объекта из-за пределы Словаря, корреспондент ключ не удаляется из словаря, чего я не ожидал.

Что я хотел достичь, так это то, что когда объект удаляется извне dict, ключ также исчезает из dict.

+0

Что вы хотите сказать, удалив объект? Покажите нам код, который не работает. – Moberg

+1

Thats, потому что экземпляр1 или экземпляр2 не ссылаются в словаре, вместо этого их хэш вычисляется и сохраняется для поиска. – dnit13

+1

Счетчик ссылок для этих объектов не может упасть до нуля, * потому что * у вас есть ссылки на них в словаре. Если вам нужно другое поведение, сделайте ключ [слабая ссылка] (https://docs.python.org/3/library/weakref.html). – jonrsharpe

ответ

2

Фактически, ваш объект, хранящийся в переменной, и объект, используемый как ключ в словаре, не совсем то же самое. Это две разные ссылки на один и тот же объект в памяти.

Давайте рассмотрим следующий пример:

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'} 

Какой prouves в Dict создал новую ссылку на основной объект. И потому, что основной метод в Python управления памятью использует подсчет ссылок:

Python поддерживает подсчет всех ссылок на объект, а когда не осталось ни одного, объект удаляется.

поэтому, если вы удалите ссылку, хранящуюся в varayable del a, ссылка, хранящаяся в дикторе, осталась.

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

И это сделает непостоянство в вас Dict, потому что у вас есть больше доступа к данным, я буду рекомендовать использовать ссылку на переменную, чтобы удалить данные из Словаря чем удалить объект.

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

перед удалением объекта, вы должны удалить ключ из словаря.

del outputs[instance1] 

Это происходит из-за того, что dict не хранит объект в качестве ключа, а хеш, который генерируется из него.

 Смежные вопросы

  • Нет связанных вопросов^_^