103 votes

Dois-je toujours spécifier un type d'exception dans les instructions `except` ?

Lorsque vous utilisez l'IDE PyCharm, l'utilisation de except: sans type d'exception déclenche un rappel de l'IDE que cette clause d'exception est Too broad .

Devrais-je ignorer ce conseil ? Ou est-ce que c'est Python de toujours spécifier le type d'exception ?

99voto

babbageclunk Points 3246

Il est presque toujours préférable de spécifier un type d'exception explicite. Si vous utilisez un except: vous pouvez finir par attraper des exceptions autres que celles que vous vous attendez à attraper - cela peut cacher des bogues ou rendre plus difficile le débogage des programmes lorsqu'ils ne font pas ce que vous attendez.

Par exemple, si vous insérez une ligne dans une base de données, vous voudrez peut-être attraper une exception qui indique que la ligne existe déjà, afin de pouvoir effectuer une mise à jour.

try:
    insert(connection, data)
except:
    update(connection, data)

Si vous spécifiez un except: vous pourriez également obtenir une erreur de socket indiquant que le serveur de la base de données s'est effondré. Il est préférable de n'attraper que les exceptions que vous savez comment traiter - il est souvent préférable que le programme échoue à l'endroit de l'exception plutôt que de continuer mais de se comporter de manière étrange et inattendue.

Un cas où vous pourriez vouloir utiliser un simple except: est au niveau supérieur d'un programme que vous devez toujours exécuter, comme un serveur de réseau. Mais alors, vous devez faire très attention à enregistrer les exceptions, sinon il sera impossible de comprendre ce qui ne va pas. Fondamentalement, il ne devrait y avoir qu'un seul endroit dans un programme qui fait cela.

Un corollaire à tout cela est que votre code ne devrait jamais faire raise Exception('some message') car il oblige le code client à utiliser except: (ou except Exception: qui est presque aussi mauvais). Vous devriez définir une exception spécifique au problème que vous voulez signaler (peut-être en héritant d'une sous-classe d'exception intégrée comme ValueError o TypeError ). Ou vous devriez lever une exception intégrée spécifique. Cela permet aux utilisateurs de votre code d'être attentifs à ne capturer que les exceptions qu'ils veulent gérer.

43voto

AsheeshR Points 2780

Vous ne devez pas ignorer les conseils que vous donne l'interprète.

Desde el PEP-8 Guide de style pour Python :

Lorsque vous attrapez des exceptions, mentionnez les exceptions spécifiques chaque fois que au lieu d'utiliser une simple clause except :.

Par exemple, utilisez :

 try:
     import platform_specific_module 
 except ImportError:
     platform_specific_module = None 

Une clause except : dépouillée attrapera les exceptions SystemExit et KeyboardInterrupt, ce qui rendra plus difficile la d'interrompre un programme avec Control-C, et peut masquer d'autres problèmes. Si vous souhaitez attraper toutes les exceptions qui signalent des erreurs de programme, utilisez la clause except Exception : (except nu est équivalent à except BaseException :).

Une bonne règle générale consiste à limiter l'utilisation de clauses nues "sauf" à deux cas :

Si le gestionnaire d'exception doit imprimer ou consigner l'information suivante au moins l'utilisateur saura qu'une erreur s'est produite. Si le code doit effectuer un travail de nettoyage, mais laisse ensuite l'exception se propager vers le haut avec raise. l'exception se propager vers le haut avec raise. try...finally peut être une meilleure façon de gérer ce cas.

9voto

Tony Hopkinson Points 15160

Ce n'est pas spécifique à Python.

L'objectif des exceptions est de traiter le problème aussi près que possible de son origine.

Vous gardez donc le code qui, dans des circonstances exceptionnelles, pourrait déclencher le problème et la résolution "à côté" l'un de l'autre.

Le problème, c'est qu'il est impossible de connaître toutes les exceptions qui peuvent être levées par un morceau de code. Tout ce que vous pouvez savoir, c'est que s'il s'agit d'une exception de type "fichier non trouvé", vous pouvez la piéger et demander à l'utilisateur d'en trouver un qui fonctionne ou d'annuler la fonction.

Si vous mettez un try catch autour de cela, alors peu importe le problème qu'il y avait dans votre routine de fichier (lecture seule, permissions, UAC, pas vraiment un pdf, etc.), tout le monde tombera sur votre catch de fichier non trouvé, et votre utilisateur criera "mais il est là, ce code est merdique".

Il y a maintenant quelques situations où vous pouvez tout attraper, mais elles doivent être choisies consciemment.

Il s'agit d'attraper, d'annuler une action locale (comme la création ou le verrouillage d'une ressource, (l'ouverture d'un fichier sur le disque pour l'écriture par exemple), puis de relancer l'exception pour qu'elle soit traitée à un niveau supérieur).

L'autre toi est que tu ne te soucies pas de savoir pourquoi ça a mal tourné. L'impression par exemple. Vous pourriez avoir un piège autour de cela, pour dire Il y a un problème avec votre imprimante, veuillez le régler, et ne pas tuer l'application à cause de cela. De la même manière, si votre code exécutait une série de tâches séparées en utilisant une sorte de programme, vous ne voudriez pas que l'ensemble de l'application s'arrête parce que l'une des tâches a échoué.

Remarque Si vous faites ce qui précède, je ne saurais trop vous recommander une sorte de journalisation des exceptions, par exemple try catch log end.

4voto

Ulrich Eckhardt Points 5381

Vous attraperez également Control-C avec cela, donc ne le faites pas à moins de le "lancer" à nouveau. Cependant, dans ce cas, vous devriez plutôt utiliser "finally".

4voto

Pavel Anossov Points 23610

Spécifiez toujours le type d'exception, il existe de nombreux types d'exceptions que vous ne voulez pas attraper, comme par exemple SyntaxError , KeyboardInterrupt , MemoryError etc.

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