Это правда, что единственный правильный способ указать на ошибку в конструкторе - вызвать исключение. Вот почему в C ++ и в других объектно-ориентированных языках, которые были разработаны с учетом безопасности исключений, деструктор не вызывается, если в конструктор объекта выдается исключение (что означает, что инициализация объекта не завершена). Это часто не относится к языкам сценариев, таким как Python. Например, следующий код выдает AttributeError в случае сбоя socket.connect ():
class NetworkInterface:
def __init__(self, address)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect(address)
self.stream = self.socket.makefile()
def __del__(self)
self.stream.close()
self.socket.close()
Причина в том, что деструктор незавершенного объекта вызывается после неудачной попытки подключения до инициализации атрибута потока. Вы не должны избегать создания исключений из конструкторов, я просто говорю, что на Python сложно написать полностью безопасный код исключений. Некоторые разработчики Python вообще избегают использования деструкторов, но это вопрос другого спора.