首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python 3,super.__del__()

Python 3,super.__del__()
EN

Stack Overflow用户
提问于 2016-04-19 23:08:23
回答 3查看 4.9K关注 0票数 9

我在我定义的类中有一个__del__方法,用于删除通过在ctypes接口中调用C++ C++而创建的一些新对象。当我的类的一个实例被销毁时,我想删除这些对象。我有一个如下所示的类片段:

代码语言:javascript
复制
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__()时,我得到了错误消息:

代码语言:javascript
复制
super().__del__()
AttributeError: 'super' object has no attribute '__del__'

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

EN

回答 3

Stack Overflow用户

发布于 2016-04-20 04:45:51

__del__的作用不是删除对象:它是在自动删除对象之前调用的。因此,如果您的父类没有定义__del__,也没什么问题。如果super().__del__()困扰您,请不要联系它。

根据记录,对象没有默认__del__的原因是带有__del__的对象在引用循环的情况下没有被垃圾收集(直到Python3.4)。有关详细信息,请阅读gc.garbage in Python 3.3gc.garbage in Python 3.4的文档。

票数 5
EN

Stack Overflow用户

发布于 2016-04-19 23:55:14

您所派生的类没有__del__()。因此,试图调用它是一个错误。

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

下面是每种方法的一个示例:

代码语言:javascript
复制
# 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)
票数 4
EN

Stack Overflow用户

发布于 2020-01-23 09:38:42

official documentation

实例即将销毁时调用

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

如果我错了,请纠正我。如果基类不提供__del__,则不必调用它。捕获AttributeError并忽略它是一个很好的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36722390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档