编程语言
首页 > 编程语言> > 在python __del__处理期间删除子类之前的基类

在python __del__处理期间删除子类之前的基类

作者:互联网

语境

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

我正在为logging.Handler写一个子类.关闭实例后,它将一个哨兵值发布到Queue.Queue.如果没有,第二个线程将永远运行,等待Queue.Queue.get()完成.

我正在考虑其他开发人员时编写此代码,因此我不希望在处理程序对象上调用close()失败而导致程序挂起.

因此,我在__del __()中添加了一个检查以确保正确关闭了该对象.

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

问题

这是一些简单的示例代码:

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_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

似乎在调用x .__ del __()之前已删除了Base的定义.

__del __()上的Python文档警告说,子类需要调用基类才能进行干净删除,但是在这里看来这是不可能的.

看到我迈出的糟糕一步了吗?

解决方法:

您的代码有些误导,我尝试了一下,但正如您所描述的那样失败了.但是后来我写了这样的话:

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.

因此,我想您不能在解释器关闭期间依赖__del__方法(我认为类对象是在实例之前收集的?),但在此之前它们将按预期工作.

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

标签:destructor,python
来源: https://codeday.me/bug/20191210/2098733.html