删除用作字典中键的对象不会删除字典中对应的键
Deleting an object used as key in dict does not remove the correspondent key in the dict
我有一个以对象实例作为键的字典:
outputs = {instance1:instance1.id, instance2:instance2.id}
当我从字典外删除对象时,相应的键并没有从字典中删除,这不是我所期望的。
我想实现的是当字典外的对象被删除时,key也从字典中消失。
在删除对象之前,您必须从字典中删除键。
del outputs[instance1]
发生这种情况是因为 dict 没有将对象存储为键,而是从中生成的散列。
实际上你存储在变量中的对象和字典中用作键的对象并不完全相同。它们是对内存中同一个对象的两个不同引用。
举个例子:
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'}
这证明字典创建了对主对象的新引用。并且因为 Python 的主要内存管理方法使用引用计数:
Python keeps a count of all the references to
the object, and when there are none left, the object is deleted.
因此,如果您删除存储在变量 del a
中的引用,则存储在字典中的引用将保留。
del a
print(sys.getrefcount(d.keys()[0]) - 1) # Out: 1
这会使你的字典变得不稳定,因为你对你的数据有更多的访问权限,我建议使用变量引用从字典中删除数据,而不是删除对象。
del d[a]
print(sys.getrefcount(a) - 1) # Out: 1
del a
我有一个以对象实例作为键的字典:
outputs = {instance1:instance1.id, instance2:instance2.id}
当我从字典外删除对象时,相应的键并没有从字典中删除,这不是我所期望的。
我想实现的是当字典外的对象被删除时,key也从字典中消失。
在删除对象之前,您必须从字典中删除键。
del outputs[instance1]
发生这种情况是因为 dict 没有将对象存储为键,而是从中生成的散列。
实际上你存储在变量中的对象和字典中用作键的对象并不完全相同。它们是对内存中同一个对象的两个不同引用。
举个例子:
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'}
这证明字典创建了对主对象的新引用。并且因为 Python 的主要内存管理方法使用引用计数:
Python keeps a count of all the references to the object, and when there are none left, the object is deleted.
因此,如果您删除存储在变量 del a
中的引用,则存储在字典中的引用将保留。
del a
print(sys.getrefcount(d.keys()[0]) - 1) # Out: 1
这会使你的字典变得不稳定,因为你对你的数据有更多的访问权限,我建议使用变量引用从字典中删除数据,而不是删除对象。
del d[a]
print(sys.getrefcount(a) - 1) # Out: 1
del a