Context
Мне известно, что если я задам вопрос о деструкторах 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
Кажется, определение Base удалено до вызова x.__del__()
.
Документация Python по __del __ () предупреждает, что подкласс должен вызвать базовый класс, чтобы получить чистое удаление, но здесь это кажется невозможным.
Вы видите, где я сделал плохой шаг?