Y a-t-il une différence entre «lever exception ()» et «lever l'exception» sans parenthèses?

100

Définition d'une exception sans paramètre:

class MyException(Exception):
    pass

Lorsqu'il est soulevé, y a-t-il une différence entre:

raise MyException

et

raise MyException()

Je n'ai pas pu en trouver; est-ce simplement une syntaxe surchargée?

Ohad Dan
la source
1
Lisez cette réponse: stackoverflow.com/questions/13052991/…
satoru
1
Ce n'est pas à proprement parler syntaxique. Python ne peut pas savoir s'il obtiendra une classe ou une instance avant l'exécution.
asmeurer le

Réponses:

116

La réponse courte est que les deux raise MyExceptionet raise MyException()faire la même chose. Ce premier formulaire instancie automatiquement votre exception.

La section appropriée de la documentation dit: " rise évalue la première expression comme objet d'exception. Il doit s'agir d'une sous-classe ou d'une instance de BaseException. S'il s'agit d'une classe, l'instance d'exception sera obtenue en cas de besoin en instanciant la classe avec pas d'arguments. "

Cela dit, même si la sémantique est la même, la première forme est microscopiquement plus rapide, et la seconde forme est plus flexible (car vous pouvez lui transmettre des arguments si nécessaire).

Le style habituel que la plupart des gens utilisent en Python (c'est-à-dire dans la bibliothèque standard, dans les applications courantes et dans de nombreux livres) est à utiliser raise MyExceptionlorsqu'il n'y a pas d'arguments. Les utilisateurs n'instancient l'exception directement que lorsque certains arguments doivent être passés. Par exemple: raise KeyError(badkey).

Raymond Hettinger
la source
18
Pourquoi la première forme (sans parenthèses) serait-elle microscopiquement plus rapide?
jamesdlin
15
@jamesdlin Parce que le code C à instancier automatiquement n'a pas la surcharge interprétée que celle que vous avez faite vous-même.
Raymond Hettinger
4

Allez regarder les documents pour la raisedéclaration . Il crée une instance de MyException.

Jason Fried
la source
1
Il est intéressant de noter que la syntaxe deraise a un peu changé en Python 3. La partie qui concerne cette question est la même ( raise ExceptionTypecrée toujours une instance du type en appelant son constructeur sans argument).
Blckknght
0

Oui, il y a une différence entre ValueErroretValueError()

ValueErrorest une classe alors que ValueError()crée une instance d'une classe. C'est la raison pour laquelle type(ValueError) is typeettype(ValueError()) is ValueError

Le seul but de raiseest de soulever l'exception,

lorsque nous utilisons ValueError, la classe sera appelée qui à son tour exécute le constructeur ValueError()

lorsque nous utilisons ValueError(), la méthode ValueError()est directement appelée.

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

Ranjith Udayakumar
la source