É considerado péssimo criar exceções __init__
? Em caso afirmativo, qual é o método aceito de gerar um erro quando determinadas variáveis de classe são inicializadas como None
ou de um tipo incorreto?
É considerado péssimo criar exceções __init__
? Em caso afirmativo, qual é o método aceito de gerar um erro quando determinadas variáveis de classe são inicializadas como None
ou de um tipo incorreto?
Respostas:
Criar exceções dentro __init__()
é absolutamente bom. Não há outra boa maneira de indicar uma condição de erro em um construtor, e há muitas centenas de exemplos na biblioteca padrão em que a construção de um objeto pode gerar uma exceção.
A classe de erro a ser levantada, é claro, depende de você. ValueError
é melhor se o construtor recebeu um parâmetro inválido.
ValueError
e TypeError
.
__init__
não é o construtor, é o inicializador. Você pode querer editar a linha Não há outra boa maneira de indicar uma condição de erro dentro de um construtor, ..
É verdade que a única maneira adequada de indicar um erro em um construtor é gerar uma exceção. É por isso que em C ++ e em outras linguagens orientadas a objetos que foram projetadas com a segurança de exceções em mente, o destruidor não é chamado se uma exceção for lançada no construtor de um objeto (o que significa que a inicialização do objeto está incompleta). Geralmente, esse não é o caso de linguagens de script, como Python. Por exemplo, o código a seguir lança um AttributeError se socket.connect () falhar:
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()
O motivo é que o destruidor do objeto incompleto é chamado após a tentativa de conexão falhar, antes que o atributo do fluxo tenha sido inicializado. Você não deve evitar lançar exceções de construtores, apenas estou dizendo que é difícil escrever um código totalmente seguro para exceção em Python. Alguns desenvolvedores de Python evitam o uso de destruidores por completo, mas isso é assunto de outro debate.
__del__
porque é mal escrito. Você teria exatamente o mesmo problema se tivesse this->p_socket->close()
um destruidor em C ++. No C ++, você não faria isso - deixaria o objeto membro se destruir. Faça o mesmo em python.
Não vejo nenhuma razão para que esteja em má forma.
Pelo contrário, uma das coisas pelas quais as exceções são conhecidas por se sair bem, em vez de retornar códigos de erro, é que os códigos de erro geralmente não podem ser retornados pelos construtores. Portanto, pelo menos em linguagens como C ++, gerar exceções é a única maneira de sinalizar erros.
Eu acho que é o caso perfeito para a ValueError
exceção embutida .
Eu concordo com todas as opções acima.
Realmente, não há outra maneira de sinalizar que algo deu errado na inicialização de um objeto além de gerar uma exceção.
Na maioria das classes de programas em que o estado de uma classe depende totalmente das entradas para essa classe, podemos esperar que algum tipo de ValueError ou TypeError seja gerado.
Classes com efeitos colaterais (por exemplo, um que cria redes ou gráficos) podem gerar um erro no init se (por exemplo) o dispositivo de rede não estiver disponível ou o objeto de tela não puder ser gravado. Isso me parece sensato, porque muitas vezes você quer saber sobre as condições de falha o mais rápido possível.