2009-02-05 12 views
21

j'ai trouvé le comportement suivant au moins bizarre:retour mange exception

def errors(): 
    try: 
     ErrorErrorError 
    finally: 
     return 10 

print errors() 
# prints: 10 
# It should raise: NameError: name 'ErrorErrorError' is not defined 

L'exception disparaît lorsque vous utilisez return dans une clause finally. Est-ce un bug? Est-ce documenté n'importe où?

Mais la vraie question (et la réponse que je vais marquer comme correcte) est:
Quelle est la raison des développeurs python d'autoriser ce comportement étrange?

Répondre

30

Vous avez demandé le raisonnement des développeurs Python. Je ne peux pas parler pour eux, mais aucun autre comportement n'a de sens. Une fonction peut renvoyer une valeur ou déclencher une exception. ça ne peut pas faire les deux. Le but d'une clause "finally" est de fournir un code de nettoyage "garanti" à exécuter, quelles que soient les exceptions. En plaçant une déclaration return dans une clause finally, vous avez déclaré que vous souhaitez renvoyer une valeur, peu importe les circonstances, indépendamment des exceptions. Si Python se comportait comme vous le demandiez et levait l'exception, ce serait briser le contrat de la clause "finally" (car il ne retournerait pas la valeur que vous lui avez dit de retourner).

+3

Comportement raisonnable: interdire statiquement 'return' de' enfin'. C'est déroutant comme on le voit. – Elazar

3

De retour d'un est finalement pas une bonne idée. Je sais que C# interdit spécifiquement de le faire.

51

L'exception disparaît lorsque vous utilisez return dans une clause finally. .. Est-ce documenté quelque part?

It is:

Si finalement est présent, il spécifie un gestionnaire de « nettoyage ». La clause try est exécutée, y compris les clauses except et else. Si une exception se produit dans l'une des clauses et n'est pas gérée, l'exception est temporairement enregistrée. La clause finally est exécutée. S'il existe une exception enregistrée, elle est relancée à la fin de la clause finally. Si la clause finally déclenche une autre exception ou exécute une instruction return ou break, l'exception enregistrée est perdue.

4

Voici une comparaison intéressante pour le retour dans le bloc enfin, entre - Java/C#/Python/JavaScript: http://www.gettingclever.com/2008/07/return-from-finally.html

+2

Aucune surprise ici. Toutes les langues font la seule chose sensible (honorer la clause finale), sauf C#, ce qui empêche de vous tirer dans le pied. Ce ne serait pas dans l'esprit de Python, qui vous donne toujours toute la corde dont vous avez besoin pour vous pendre :-) "Nous sommes tous des adultes consentants ici." –

+0

Lien rompu: https://web.archive.org/web/20120426091446/http://www.gettingclever.com/2008/07/return-from-finally.html – Harvey