在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