Python 3,super .__ del __()

inw*_*ack 6 python destructor super python-3.x

__del__在我定义的类中有一个方法,删除一些通过在ctypes接口中调用C++ new创建的C++对象.我想删除我的类的实例时删除这些对象.我有一个这里显示的类的片段:

class Graph(QtCore.QObject):
    def __init__(self):
        super().__init__()
        #list of objects created by calls to ctypes to create pointers to C++ objects which are instantiated with C++ new 
        self.graphs = []

    def __del__(self):
        print("in delete method")
        for graph in self.graphs:
            # call the C++ delete to free the storage used by this graph
            myctypes.graphDelete(graph)
        super().__del__()
Run Code Online (Sandbox Code Playgroud)

当我的Graph类的一个实例被删除时,该__del__方法被调用,我看到我的print语句,当我在C++代码中的析构函数方法中设置一个断点时,正如预期的那样,它删除了该对象.但是,当我的__del__方法调用时super().__del__(),我收到错误消息:

super().__del__()
AttributeError: 'super' object has no attribute '__del__'
Run Code Online (Sandbox Code Playgroud)

如果我__del__在子类中定义自己的方法或者是否会自动删除父类,如何确保删除父类(QtCore.QObject)?

And*_*ini 5

作用__del__不是删除对象:在对象自动删除之前调用。因此,如果您的父类没有定义__del__. super().__del__()如果它打扰你,请随意不要打电话。

作为记录,对象没有默认值的原因__del____del__在引用循环的情况下没有垃圾收集对象(直到 Python 3.4)。有关更多信息,请阅读Python 3.3中的gc.garbage 和 Python 3.4 中的 gc.garbage的文档。

  • 如果您有一个引用循环,并且循环中的对象之一具有“__del__”,则这些对象永远不会被释放。参见[3.3中的gc.garbage](https://docs.python.org/3.3/library/gc.html#gc.garbage)和[3.4中的gc.garbage](https://docs.python.org/ 3.4/library/gc.html#gc.garbage) (2认同)

kin*_*all 4

您派生的班级没有__del__(). 所以尝试调用它是一个错误。

现在,如果您希望您的类在多重继承场景中使用,则方法解析顺序 (MRO) 中的下一个类实际上可能不是您的类的父类。而那个类,无论它是什么,都可能有一个__del__()方法。因此,如果您担心这种情况,您可以使用try并吞下AttributeError、 或使用hasattr()、 或getattr()与虚拟 lambda 一起使用作为默认值。

下面是每个的示例:

# there is a minor bug here, can you guess what it is?
try:
    super().__del__(self)
except AttributeError:
    pass

# better versions of the above
s = super()
try:
    s.__del__
except AttributeError:
    pass
else:
    s.__del__(self)

# alternative 2
s = super()
if hasattr(s, "__del__"): 
    s.__del__(self)

# alternative 3
getattr(super(), "__del__", lambda self: None)(self)
Run Code Online (Sandbox Code Playgroud)