662 votes

Python try-else

Quelle est l'utilisation prévue de l'option else clause de la try déclaration ?

3 votes

La plupart des réponses semblent se concentrer sur la raison pour laquelle nous ne pouvons pas simplement mettre le matériel dans la clause else dans la clause try elle-même. La question stackoverflow.com/questions/3996329 demande spécifiquement pourquoi le code de la clause else ne peut pas aller après le bloc try lui-même, et cette question est doublée de celle-ci, mais je ne vois pas de réponse claire à cette question ici. Je pense que stackoverflow.com/a/3996378/1503120 répond parfaitement à cette question. J'ai également essayé d'élucider les différentes significations des différentes clauses à stackoverflow.com/a/22579805/1503120 .

2 votes

Vous voulez que quelque chose se produise si l'exception ne se déclenche pas, avant le nettoyage final, qui n'est jamais censé déclencher lui-même le même traitement de l'exception.

0 votes

Après avoir oublié ce que else fait dans try/else y for/else de nombreuses fois, je l'ai mentalement aliasé avec noexcept y nobreak dans ces contextes respectifs. Personnellement, je trouve qu'il s'agit d'une surcharge si malheureuse du mot que j'essaie d'éviter de l'utiliser si je le peux, car cela oblige les personnes qui lisent du code à se demander "à quoi sert cette chose déjà ?". Habituellement, un drapeau, un continue o break La déclaration peut relayer ce que j'essaie d'exprimer avec quelques lignes supplémentaires, mais certainement plus de clarté (si la popularité de la question est une indication).

951voto

Blair Conrad Points 56195

Les déclarations dans le else sont exécutés si l'exécution tombe en bas du try - s'il n'y avait pas d'exception. Honnêtement, je n'en ai jamais trouvé le besoin.

Cependant, Traitement des exceptions notes :

L'utilisation de la clause else est préférable que l'ajout de code supplémentaire à la clause try car elle évite d'attraper accidentellement accidentellement une exception qui n'a pas été levée par le code protégé par la clause l'instruction try ... except.

Donc, si vous avez une méthode qui pourrait, par exemple, lancer un IOError et vous voulez attraper les exceptions qu'elle soulève, mais il y a autre chose que vous voulez faire si la première opération réussit, et vous Ne le fais pas. si vous voulez attraper une erreur IOError lors de cette opération, vous pouvez écrire quelque chose comme ceci :

try:
    operation_that_can_throw_ioerror()
except IOError:
    handle_the_exception_somehow()
else:
    # we don't want to catch the IOError if it's raised
    another_operation_that_can_throw_ioerror()
finally:
    something_we_always_need_to_do()

Si vous mettez juste another_operation_that_can_throw_ioerror() après operation_that_can_throw_ioerror le except rattraperait les erreurs du second appel. Et si vous le mettez après tout le try il sera toujours exécuté, et pas avant que le bloc finally . Le site else vous permet de vous assurer

  1. la seconde opération n'est exécutée que s'il n'y a pas d'exception,
  2. il est exécuté avant le finally le bloc, et
  3. tout IOError qu'il soulève ne sont pas prises ici

9 votes

Gardez également à l'esprit que les variables utilisées dans le bloc try PEUVENT être utilisées dans le bloc else, donc vous devriez toujours envisager d'utiliser cette variante si vous ne prévoyez pas d'autres exceptions dans le bloc else.

3 votes

Cela n'a pas d'importance, car les variables de l'essai sont vues en dehors de l'essai, qu'il y ait un else ou non.

46 votes

Il n'existe pas de "variable try-scoped". En Python, la portée des variables est établie uniquement par les modules, les fonctions et les compréhensions, et non par les structures de contrôle.

124voto

Izkata Points 3634

Il y a un gran raison d'utiliser else - le style et la lisibilité. C'est généralement une bonne idée de garder le code qui peut provoquer des exceptions près du code qui les traite. Par exemple, comparez-les :

try:
    from EasyDialogs import AskPassword
    # 20 other lines
    getpass = AskPassword
except ImportError:
    getpass = default_getpass

y

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
else:
    # 20 other lines
    getpass = AskPassword

Le second est bon lorsque le except ne peut pas revenir plus tôt, ou relancer l'exception. Si possible, j'aurais écrit :

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
    return False  # or throw Exception('something more descriptive')

# 20 other lines
getpass = AskPassword

Note : Réponse copiée d'un duplicata récemment posté aquí d'où toute cette histoire de "AskPassword".

60voto

Darius Bacon Points 9741

Une utilisation : tester un code qui devrait lever une exception.

try:
    this_should_raise_TypeError()
except TypeError:
    pass
except:
    assert False, "Raised the wrong exception type"
else:
    assert False, "Didn't raise any exception"

(Ce code devrait être abstrait dans un test plus générique en pratique).

20voto

RoadieRich Points 303

Je trouve cela très utile lorsque vous avez un nettoyage à faire qui doit être fait même s'il y a une exception :

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()

11voto

Unknown Points 22789

Même si vous ne pouvez pas penser à une utilisation pour le moment, vous pouvez être sûr qu'il y en aura une. Voici un exemple peu imaginatif :

Avec else :

a = [1,2,3]
try:
    something = a[2]
except:
    print "out of bounds"
else:
    print something

Sans else :

try:
    something = a[2]
except:
    print "out of bounds"

if "something" in locals():
    print something

Ici, vous avez la variable something défini si aucune erreur n'est déclenchée. Vous pouvez supprimer ce paramètre en dehors de l'élément try mais il faut alors détecter si une variable est définie.

4 votes

Quel est le problème avec something = a[2]; print something à l'intérieur du bloc try: ?

0 votes

@ S.Lott rien, mais que faire si quelqu'un vous envoie une liste, et que vous ne voulez pas afficher les données si elles ne sont pas assez longues car elles sont probablement corrompues ?

13 votes

S. Lott : "imprimer quelque chose" pourrait lever une exception différente que vous ne voulez pas intercepter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X