¿Se considera mala forma de hacer excepciones dentro __init__
? Si es así, ¿cuál es el método aceptado para arrojar un error cuando ciertas variables de clase se inicializan como None
o de un tipo incorrecto?
¿Se considera mala forma de hacer excepciones dentro __init__
? Si es así, ¿cuál es el método aceptado para arrojar un error cuando ciertas variables de clase se inicializan como None
o de un tipo incorrecto?
Respuestas:
Elevar excepciones dentro __init__()
está absolutamente bien. No hay otra buena manera de indicar una condición de error dentro de un constructor, y hay muchos cientos de ejemplos en la biblioteca estándar donde construir un objeto puede generar una excepción.
La clase de error a plantear, por supuesto, depende de usted. ValueError
es mejor si el constructor pasó un parámetro no válido.
ValueError
y TypeError
.
__init__
no es el constructor, es el intializador. Es posible que desee editar la línea No hay otra buena manera de indicar una condición de error dentro de un constructor, ..
Es cierto que la única forma correcta de indicar un error en un constructor es generar una excepción. Es por eso que en C ++ y en otros lenguajes orientados a objetos que se han diseñado teniendo en cuenta la seguridad de la excepción, no se llama al destructor si se produce una excepción en el constructor de un objeto (lo que significa que la inicialización del objeto está incompleta). Este no suele ser el caso en los lenguajes de secuencias de comandos, como Python. Por ejemplo, el siguiente código arroja un AttributeError si socket.connect () falla:
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()
La razón es que se llama al destructor del objeto incompleto después de que el intento de conexión ha fallado, antes de que se haya inicializado el atributo de flujo. No debe evitar arrojar excepciones de los constructores, solo digo que es difícil escribir código seguro de excepciones en Python. Algunos desarrolladores de Python evitan usar destructores por completo, pero eso es otro tema de debate.
__del__
porque está mal escrito. Tendría exactamente el mismo problema si lo hiciera this->p_socket->close()
en un destructor en C ++. En C ++, no haría eso, dejaría que el objeto miembro se destruya a sí mismo. Haz lo mismo en python.
No veo ninguna razón para que sea una mala forma.
Por el contrario, una de las cosas por las que se sabe que las excepciones funcionan bien, en lugar de devolver códigos de error, es que los constructores no pueden devolver los códigos de error . Entonces, al menos en lenguajes como C ++, generar excepciones es la única forma de señalar errores.
Debería pensar que es el caso perfecto para la ValueError
excepción incorporada .
Estoy de acuerdo con todo lo anterior.
Realmente no hay otra forma de indicar que algo salió mal en la inicialización de un objeto que no sea generar una excepción.
En la mayoría de las clases de programas donde el estado de una clase depende totalmente de las entradas a esa clase, podríamos esperar que se genere algún tipo de ValueError o TypeError.
Las clases con efectos secundarios (p. Ej., Una red o gráficos) pueden generar un error en init si (por ejemplo) el dispositivo de red no está disponible o no se puede escribir en el objeto del lienzo. Esto me parece razonable porque a menudo quieres saber sobre las condiciones de falla lo antes posible.