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