简体   繁体   English

在python中删除继承的dict元素

[英]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.keyslist构造函数:因此,在迭代之前,您将获得一个包含现有键的快照的列表:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM