[英]Deleting inherited dict elements in python
I have a dict of Objects which are to be destroyed as follows. 我有一个对象的字典,该对象将按以下方式销毁。
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
When try this I am geting this error 当尝试这个我得到这个错误
RuntimeError: dictionary changed size during iteration
You are using Python 3.x and the "keys" method gives you a live view of the dictionary keys. 您正在使用Python 3.x,并且“ keys”方法为您提供了字典键的实时视图。 When these change, due to you deleting items, Python can't consistently continue iterating over them.
当这些更改更改时,由于您删除了项目,Python无法始终如一地继续迭代它们。
To fix it, just pass your call to self.keys
to the list
constructor: therefore you get a list with a snapshot of the existing keys prior to the iteration: 要解决此问题,只需
self.keys
的调用self.keys
给list
构造函数:因此,在迭代之前,您将获得一个包含现有键的快照的列表:
def __del__():
for k in list(self.keys()):
del self[k]
Now, there are some tricks here and there for proper subclassing a dict that might take you by surprise. 现在,这里有一些技巧可以适当地继承一个字典,这可能会让您感到惊讶。 If the only behavior you want is to explictly delete your elements on dict deletion, there is no need for that at all - otherwise, see the docs about collection.UserDict - which makes subclassing easier, or collections.abc.MutableSequence - both will warrant you full dict behavior with the need to override a minimum set of methods.
如果您想要的唯一行为是在删除dict时显式删除元素,则根本不需要这样做-否则,请参阅有关collection.UserDict的文档-使子类化更加容易,或者请参见collections.abc.MutableSequence-两者都应保证您需要使用最少的方法集来完成dict行为。
One other note: it is not considered good practice in Python to rely on __del__
to actually be run when your objects go out of scope: there might be other references to them, and them del self.key[x]
simply won't call the __del__
method on the object. 另一个注意事项:在对象超出范围时,实际上依靠
__del__
来运行不是Python的好习惯:可能还有其他引用,它们del self.key[x]
根本不会调用对象上的__del__
方法。 And during interpreter shutdown (At the end of your program), there is no guarantee at all __del__
will be called even for objects that correctly are no longer referenced. 而且在解释器关闭期间(在程序结尾),即使对于不再正确引用的对象,也无法保证会完全调用
__del__
。
You'd better add a explicit delete
(not special __del__
) method and call it instead of relying on the del
statement mechanism. 您最好添加一个显式
delete
(不是特殊的__del__
)方法并调用它,而不要依赖于del
语句机制。
It's better not to delete item while iterating. 最好不要在迭代时删除项目。 Actually I don't see there is any need to override
__del__
. 实际上,我认为没有必要重写
__del__
。 Simply using: 只需使用:
class DerivedDict(dict):
def __init__(self):
super(DerivedDict, self).__init__()
This will also cause __del__
of Elem
being called. 这也会导致
__del__
Elem
被调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.