C'è una differenza tra "solleva eccezione ()" e "solleva eccezione" senza parentesi?


99

Definizione di un'eccezione senza parametri:

class MyException(Exception):
    pass

Quando sollevato, c'è qualche differenza tra:

raise MyException

e

raise MyException()

Non ho trovato nessuno; è semplicemente una sintassi sovraccarica?



1
A rigor di termini non è sintattico. Python non può sapere se otterrà una classe o un'istanza fino al runtime.
asmeurer

Risposte:


114

La risposta breve è che entrambi raise MyExceptione raise MyException()fanno la stessa cosa. Questo primo modulo crea automaticamente un'istanza della tua eccezione.

La sezione pertinente dei documenti dice: " raise valuta la prima espressione come oggetto eccezione. Deve essere una sottoclasse o un'istanza di BaseException. Se si tratta di una classe, l'istanza di eccezione verrà ottenuta quando necessario istanziando la classe con nessun argomento. "

Detto questo, anche se la semantica è la stessa, la prima forma è microscopicamente più veloce e la seconda forma è più flessibile (perché puoi passargli argomenti se necessario).

Il solito stile che la maggior parte delle persone usa in Python (cioè nella libreria standard, nelle applicazioni più diffuse e in molti libri) è quello di usare raise MyExceptionquando non ci sono argomenti. Le persone istanziano direttamente l'eccezione solo quando è necessario passare alcuni argomenti. Ad esempio: raise KeyError(badkey).


18
Perché la prima forma (senza parentesi) dovrebbe essere microscopicamente più veloce?
jamesdlin

15
@jamesdlin Perché il codice C per istanziare automaticamente non ha l'overhead interpretato che proviene da te che effettui la chiamata.
Raymond Hettinger


0

Sì, c'è una differenza tra ValueErroreValueError()

ValueErrorè una classe mentre ValueError()crea un'istanza di una classe. Questo è il motivo per cui type(ValueError) is typeetype(ValueError()) is ValueError

L'unico scopo di raiseè sollevare l'eccezione,

quando usiamo ValueError, verrà chiamata la classe che a sua volta esegue il costruttore ValueError()

quando usiamo ValueError(), il metodo ValueError()viene chiamato direttamente.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.