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?


1

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


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


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.