Python 3,super .__ del __()

时间:2016-04-19 15:08:23

标签: python python-3.x destructor super

我在已定义的类中有一个__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__()

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

super().__del__()
AttributeError: 'super' object has no attribute '__del__'

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

3 个答案:

答案 0 :(得分: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 version of the above
s = super()
try:
    s.__del__
except AttributeError:
    pass
else:
    s.__del__(self)

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

getattr(super(), "__del__", lambda self: None)(self)

答案 1 :(得分:2)

__del__的作用不是删除对象:在对象被自动删除之前,它被称为。因此,如果您的父类没有定义__del__,那就没问题了。如果它在惹你生气,请随时致电super().__del__()

对于记录,对象不具有默认__del__的原因是具有__del__的对象在参考周期的情况下不被垃圾收集(直到Python 3.4)。有关详细信息,请参阅gc.garbage in Python 3.3gc.garbage in Python 3.4

的文档

答案 2 :(得分:0)

official documentation

在实例将要销毁时调用。这也称为终结器或(不当地)析构函数。如果基类具有 del ()方法,则派生类的 del ()方法(如果有)必须显式调用它,以确保正确删除其中的基类部分实例。

如果我错了,请纠正我。如果基类不提供router.post('/login', async (req, res, next) => { var apiResponse = await authController.login(req, res, next); res.render('profile.ejs', {user: apiResponse.user}); }); ,则不必调用它。捕获__del__而忽略它是一个好方法。