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?



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


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


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.