¿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?



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).


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


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()'

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.