Gibt es einen Unterschied zwischen "Ausnahme auslösen ()" und "Ausnahme auslösen" ohne Klammern?

99

Definieren einer parameterlosen Ausnahme:

class MyException(Exception):
    pass

Gibt es einen Unterschied zwischen:

raise MyException

und

raise MyException()

Ich konnte keine finden; ist es einfach eine überladene Syntax?

Ohad Dan
quelle
1
Lesen Sie diese Antwort: stackoverflow.com/questions/13052991/…
satoru
1
Genau genommen ist es nicht syntaktisch. Python kann bis zur Laufzeit nicht wissen, ob es eine Klasse oder eine Instanz erhält.
Asmeurer

Antworten:

114

Die kurze Antwort ist, dass beide raise MyExceptionund raise MyException()dasselbe tun. Dieses erste Formular instanziiert automatisch Ihre Ausnahme.

In dem entsprechenden Abschnitt aus den Dokumenten heißt es: " Raise wertet den ersten Ausdruck als Ausnahmeobjekt aus. Es muss sich entweder um eine Unterklasse oder eine Instanz von BaseException handeln. Wenn es sich um eine Klasse handelt, wird die Ausnahmeinstanz bei Bedarf durch Instanziieren der Klasse mit abgerufen keine Argumente. "

Das heißt, obwohl die Semantik dieselbe ist, ist die erste Form mikroskopisch schneller und die zweite Form flexibler (da Sie bei Bedarf Argumente übergeben können).

Der übliche Stil, den die meisten Benutzer in Python verwenden (dh in der Standardbibliothek, in gängigen Anwendungen und in vielen Büchern), ist die Verwendung, raise MyExceptionwenn keine Argumente vorhanden sind. Die Ausnahme wird nur dann direkt instanziiert, wenn einige Argumente übergeben werden müssen. Zum Beispiel : raise KeyError(badkey).

Raymond Hettinger
quelle
18
Warum sollte die erste Form (ohne Klammern) mikroskopisch schneller sein?
Jamesdlin
15
@jamesdlin Da der automatisch zu instanziierende C-Code nicht den interpretierten Overhead hat, den Sie selbst tätigen.
Raymond Hettinger
4

Schauen Sie sich die Dokumente für die raiseAnweisung an . Es wird eine Instanz von erstellt MyException.

Jason Fried
quelle
1
Es ist erwähnenswert, dass sich die Syntax fürraise in Python 3 etwas geändert hat. Der Teil, der für diese Frage relevant ist, ist jedoch derselbe ( raise ExceptionTypeerstellt immer noch eine Instanz des Typs, indem der Konstruktor ohne Argumente aufgerufen wird).
Blckknght
0

Ja, es gibt einen Unterschied zwischen ValueErrorundValueError()

ValueErrorist eine Klasse, während ValueError()eine Instanz einer Klasse erstellt wird. Dies ist der Grund, warum type(ValueError) is typeundtype(ValueError()) is ValueError

Der einzige Zweck von raiseist es, die Ausnahme zu erheben,

Wenn wir verwenden ValueError, wird eine Klasse aufgerufen, die wiederum den Konstruktor ausführt ValueError()

Wenn wir verwenden ValueError(), wird die Methode ValueError()direkt aufgerufen.

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

Ranjith Udayakumar
quelle