我有一个将对象实例作为键的字典:
outputs = {instance1:instance1.id, instance2:instance2.id}
当我从dict外部删除对象时,对应的密钥不会从字典中删除,这不是我所期望的。
我想要实现的是当从dict外部删除对象时,该键也会从dict中消失。
答案 0 :(得分: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'}
dict为dict创建了一个对主对象的新引用。而且因为Python的主要内存管理方法使用引用计数:
Python保留所有引用的计数 对象,如果没有剩下,则删除该对象。
因此,如果删除存储在变量del a
中的引用,则存储在dict中的引用仍然存在。
del a
print(sys.getrefcount(d.keys()[0]) - 1) # Out: 1
这会使你的dict变得不稳定,因为你对数据有了更多的访问权限,我建议使用变量引用来删除dict中的数据而不是删除对象。
del d[a]
print(sys.getrefcount(a) - 1) # Out: 1
del a
答案 1 :(得分:1)
在删除对象之前,您必须从字典中删除密钥。
del outputs[instance1]
发生这种情况是因为dict不会将对象存储为键,而是从其生成的哈希值。