在python _; del _;处理期间,在子类之前删除基类

在python _; del _;处理期间,在子类之前删除基类,python,destructor,Python,Destructor,上下文 我知道,如果我问一个关于Python析构函数的问题,标准参数将是使用上下文。让我先解释一下我为什么不这么做 我正在为logging.Handler编写一个子类。当实例关闭时,它向Queue.Queue发布一个sentinel值。否则,第二个线程将永远运行,等待Queue.Queue.get()完成 我写这篇文章时考虑到了其他开发人员,所以我不希望调用处理程序对象上的close()失败而导致程序挂起 因此,我添加了一个签入_udel_u(),以确保对象已正确关闭 我理解循环引用可能会导致它

上下文

我知道,如果我问一个关于Python析构函数的问题,标准参数将是使用上下文。让我先解释一下我为什么不这么做

我正在为
logging.Handler
编写一个子类。当实例关闭时,它向Queue.Queue发布一个sentinel值。否则,第二个线程将永远运行,等待Queue.Queue.get()完成

我写这篇文章时考虑到了其他开发人员,所以我不希望调用处理程序对象上的close()失败而导致程序挂起

因此,我添加了一个签入_udel_u(),以确保对象已正确关闭

我理解循环引用可能会导致它在某些情况下失败。对此我无能为力

问题

下面是一些简单的示例代码:

explicit_delete = True

class Base:
    def __del__(self):
        print "Base class cleaning up."

class Sub(Base):
    def __del__(self):
        print "Sub-class cleaning up."
        Base.__del__(self)

x = Sub()

if explicit_delete:
    del x

print "End of thread"
当我运行此程序时,我得到了预期的结果:

Sub-class cleaning up.
Base class cleaning up.
End of thread
如果我在第一行中将
explicit\u delete
设置为
False
,我会得到:

End of thread
Sub-class cleaning up.
Exception AttributeError: "'NoneType' object has no attribute '__del__'" in <bound method Sub.__del__ of <__main__.Sub instance at 0x00F0B698>> ignored
线程结束
小班清洁。
异常AttributeError:“'NoneType'对象在忽略中没有属性'\uu del'”
似乎在调用
x.\uu del\uuu()
之前删除了Base的定义

关于_del__()的Python文档警告说,子类需要调用基类以获得干净的删除,但在这里这似乎是不可能的


你能看到我在哪里迈出了糟糕的一步吗?

一个可行但可能不是最好的解决方案:

explicit_delete = False

class Base(object):
    def __del__(self):
        print "Base class cleaning up."

class Sub(Base):
    base = Base
    def __init__(self):
        print 'stating'

    def __del__(self):
        print "Sub-class cleaning up."
        self.base.__del__(self)

x = Sub()
if explicit_delete:
    del x

print "End of thread"

在保留对基类的第二个引用的地方,您的代码有点误导,我尝试过,但正如您所描述的那样失败了。但后来我写了这样的东西:

import threading

class Base( object ):
    def __del__(self):
        print "Base class cleaning up."

class Sub(Base):
    def __del__(self):
        print "Sub-class cleaning up."
        Base.__del__( self )

def f():
    x = Sub()
    print "End of thread"

t = threading.Thread( target = f )
t.start()
t.join()
结果是:

End of thread
Sub-class cleaning up.
Base class cleaning up.
End of main thread.
因此,我想在解释器关闭期间,您不能依赖
\uuu del\uuu
方法(我认为类对象是在实例之前收集的?),但在此之前,它们的工作方式与预期的一样


也许让主线程保持活动状态直到其他线程死亡,而不在主线程中创建处理程序子类实例就足够了?

这很有趣。在我的真实代码中,它不是解释器关闭,只是线程关闭,因为另一个线程在被告知关闭之前仍在运行。我理解,当解释器关闭时,无法保证调用_del__()函数-这很好,因为我所要做的就是删除足够的引用以触发解释器关闭。