¿Hay alguna diferencia entre "generar excepción ()" y "generar excepción" sin paréntesis?

99

Definición de una excepción sin parámetros:

class MyException(Exception):
    pass

Cuando se eleva, ¿hay alguna diferencia entre:

raise MyException

y

raise MyException()

No pude encontrar ninguno; ¿Es simplemente una sintaxis sobrecargada?

Ohad Dan
fuente
1
Lea esta respuesta: stackoverflow.com/questions/13052991/…
Satoru
1
Estrictamente hablando, no es sintáctico. Python no puede saber si obtendrá una clase o una instancia hasta el tiempo de ejecución.
asmeurer

Respuestas:

114

La respuesta corta es que tanto raise MyExceptiony raise MyException()hacen lo mismo. Este primer formulario crea automáticamente una instancia de su excepción.

La sección relevante de los documentos dice: " raise evalúa la primera expresión como el objeto de excepción. Debe ser una subclase o una instancia de BaseException. Si es una clase, la instancia de excepción se obtendrá cuando sea necesario instanciando la clase con sin argumentos."

Dicho esto, aunque la semántica es la misma, la primera forma es microscópicamente más rápida y la segunda forma es más flexible (porque puede pasarle argumentos si es necesario).

El estilo habitual que la mayoría de la gente usa en Python (es decir, en la biblioteca estándar, en aplicaciones populares y en muchos libros) es usarlo raise MyExceptioncuando no hay argumentos. Las personas solo crean instancias de la excepción directamente cuando es necesario pasar algunos argumentos. Por ejemplo: raise KeyError(badkey).

Raymond Hettinger
fuente
18
¿Por qué la primera forma (sin paréntesis) sería microscópicamente más rápida?
jamesdlin
15
@jamesdlin Porque el código C para crear instancias automáticas no tiene la sobrecarga interpretada que proviene de que usted mismo hace la llamada.
Raymond Hettinger
4

Ve a la documentación para ver la raisedeclaración . Está creando una instancia de MyException.

Jason Fried
fuente
1
Vale la pena señalar que la sintaxis deraise ha cambiado un poco en Python 3. Sin embargo, la parte que es relevante para esta pregunta es la misma ( raise ExceptionTypeaún crea una instancia del tipo llamando a su constructor sin argumentos).
Blckknght
0

Sí, hay una diferencia entre ValueErroryValueError()

ValueErrores una clase mientras que ValueError()crea una instancia de una clase. Esta es la razón por la que type(ValueError) is typeytype(ValueError()) is ValueError

El único propósito de raisees plantear la excepción,

cuando usemos ValueError, se llamará a la clase que a su vez ejecuta el constructor ValueError()

cuando usamos ValueError(), el método ValueError()se llama directamente.

Nota: raise ValueError # shorthand for 'raise ValueError()'

Ranjith Udayakumar
fuente