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

Definiendo una excepción sin parámetros:

class myException(Exception): pass 

Cuando se plantea, ¿hay alguna diferencia entre:

 raise myException 

y

 raise myException() 

Al intentarlo, no pude encontrar ninguno. ¿Es simplemente una syntax sobrecargada?

La respuesta corta es que tanto el raise MyException como el raise MyException() hacen lo mismo. Este primer formulario auto instancia tu 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 al crear una instancia de la clase con sin argumentos.”

Dicho esto, a pesar de que 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 las aplicaciones populares y en muchos libros) es usar la raise MyException cuando no haya argumentos. La gente solo crea una instancia de la excepción directamente cuando hay que pasar algunos argumentos. Por ejemplo: raise KeyError(badkey) .

Ve a buscar la palabra clave raise en los documentos 6.9. La statement de aumento
Está creando una instancia de myException.

Sí, hay una diferencia entre ValueError y ValueError()

ValueError es una clase, mientras que ValueError() es un método. Esta es la razón por la que el type(ValueError) is type y el type(ValueError()) is ValueError

El único propósito de raise es elevar la excepción,

cuando usamos ValueError , se ValueError 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()'