删除 python 中继承的字典元素

Deleting inherited dict elements in python

我有一个要销毁的对象的字典,如下所示。

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

您正在使用 Python 3.x 并且 "keys" 方法为您提供了字典键的实时视图。当这些更改时,由于您删除了项目,Python 无法始终如一地继续迭代它们。

要修复它,只需将对 self.keys 的调用传递给 list 构造函数:因此您会得到一个列表,其中包含迭代前现有键的快照:

def __del__():
    for k in list(self.keys()):
        del self[k]

现在,这里和那里有一些技巧可以让您对 dict 进行适当的子类化。如果您想要的唯一行为是在 dict 删除时显式删除元素,则根本不需要这样做 - 否则,请参阅有关 collection.UserDict 的文档 - 这使得子类化更容易,或者 collections.abc.MutableSequence - 两者将保证您具有完整的 dict 行为,需要覆盖最少的方法集。

另一个注意事项:在 Python 中,当您的对象超出范围时,依赖 __del__ 实际上是 运行 并不是好的做法:可能还有其他参考资料给他们,他们 del self.key[x] 只是 不会 调用对象的 __del__ 方法。在解释器关闭期间(在程序结束时),根本无法保证 __del__ 会被调用,即使对于不再正确引用的对象也是如此。

你最好添加一个明确的 delete (不是特殊的 __del__ )方法并调用它,而不是依赖 del 语句机制。

迭代时最好不要删除项目。实际上我看不出有任何需要重写 __del__。只需使用:

class DerivedDict(dict):
    def __init__(self):
       super(DerivedDict, self).__init__()

这也会导致 Elem 中的 __del__ 被调用。