我知道,如果我问一个关于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文档警告说,子类需要调用基类以获得干净的删除,但在这里看起来是不可能的。
你能看到我在哪里做出了糟糕的一步吗?
这非常有趣。在我的* real *代码中,它不是解释器关闭,只是线程关闭,因为另一个线程仍在运行,直到它被告知关闭。我明白,当解释器关闭时,不能保证会调用__del __()函数 - 这很好,因为我所要做的就是删除足够的引用来触发解释器关闭。 – Oddthinking 2010-05-25 10:48:40