我有一个对象的字典,将被销毁如下。
class Elem:
def __init__(self, name):
self.name = name
.
.
def __del__(self):
print('destroying elem' + self.name)
class DerivedDict(dict):
def __init__(self):
super(DerivedDict, self).__init__()
def __del__():
for k in self.keys():
del self[k]
elem = Elem('myname')
ddict = DerivedDict()
ddict['myname'] = elem
# this line should delete the both the elem the entry in ddict.
del ddict
尝试此操作时,我发现此错误
RuntimeError: dictionary changed size during iteration
答案 0 :(得分:3)
您正在使用Python 3.x和"键"方法为您提供字典键的实时视图。当这些更改时,由于您删除了项目,Python无法继续迭代它们。
要修复它,只需将您的self.keys
调用传递给list
构造函数:因此,您会在迭代之前获得一个包含现有密钥快照的列表:
def __del__():
for k in list(self.keys()):
del self[k]
现在,在这里和那里有一些技巧可以正确地为一个字典创建一个可能会让你感到惊讶的字典。如果您想要的唯一行为是在dict删除时明确删除您的元素,则根本不需要 - 否则,请参阅有关collection.UserDict的文档 - 这使得子类化更容易,或者collections.abc.MutableSequence - 两者都将保证你需要覆盖一组最小的方法,你需要完整的dict行为。
另一个注意事项:当你的对象超出范围时,依靠__del__
实际运行并不是一种好的做法:可能还有其他引用,它们del self.key[x]
只需赢了就可以在对象上调用__del__
方法。在解释器关闭期间(在程序结束时),即使对于正确不再引用的对象,也无法保证所有__del__
都会被调用。
您最好添加一个明确的delete
(非特殊__del__
)方法并调用它,而不是依赖del
语句机制。
答案 1 :(得分:1)
最好不要在迭代时删除项目。实际上我没有看到有必要覆盖__del__
。只需使用:
class DerivedDict(dict):
def __init__(self):
super(DerivedDict, self).__init__()
这也会导致调用__del__
Elem
。