L'argument principal du livre est que la version d'exception du code est préférable car elle intercepte tout ce que vous pourriez avoir oublié si vous tentiez d'écrire votre propre vérification d'erreur.
Je pense que cette affirmation n’est vraie que dans des circonstances très spécifiques - où vous ne vous souciez pas de savoir si le résultat est correct.
Il ne fait aucun doute que le fait de lever des exceptions est une pratique saine et sûre. Vous devriez le faire chaque fois que vous sentez qu'il y a quelque chose dans l'état actuel du programme que vous (en tant que développeur) ne pouvez pas, ou ne voulez pas, traiter.
Votre exemple, cependant, concerne la capture d’ exceptions. Si vous attrapez une exception, vous ne vous protégez pas des scénarios que vous avez peut-être négligés. Vous faites exactement le contraire: vous supposez que vous n’avez négligé aucun scénario qui aurait pu causer ce type d’exception et vous êtes donc confiant que vous pouvez l’attraper (et l’empêcher ainsi de provoquer la fermeture du programme, comme le ferait toute exception non interceptée).
En utilisant l'approche d'exception, si vous voyez une ValueError
exception, vous sautez une ligne. En utilisant l'approche traditionnelle sans exception, vous comptez le nombre de valeurs renvoyées split
et, s'il est inférieur à 2, vous sautez une ligne. Devriez-vous vous sentir plus en sécurité avec l'approche d'exception, puisque vous auriez peut-être oublié d'autres situations "d'erreur" dans votre vérification d'erreur classique et que vous except ValueError
voudriez les résoudre?
Cela dépend de la nature de votre programme.
Si vous écrivez, par exemple, dans un navigateur Web ou un lecteur vidéo, un problème d’entrées ne devrait pas provoquer sa panne avec une exception non interceptée. Il est de loin préférable de sortir quelque chose de sensible (même si, à proprement parler, d’erreur) que de quitter.
Si vous écrivez une application dans laquelle l'exactitude est importante (comme un logiciel commercial ou d'ingénierie), ce serait une approche terrible. Si vous avez oublié certains scénarios ValueError
, la pire chose à faire est d'ignorer en silence ce scénario inconnu et de simplement sauter la ligne. C'est ainsi que des bogues très subtils et coûteux se retrouvent dans les logiciels.
Vous pourriez penser que la seule façon de voir ValueError
ce code est de split
renvoyer une seule valeur (au lieu de deux). Mais que se passe-t-il si, par la suite, votre print
déclaration commence à utiliser une expression qui soulève ValueError
certaines conditions? Cela vous fera sauter certaines lignes non pas parce qu'elles manquent :
, mais parce print
qu'elles échouent. Voici un exemple de bogue subtil auquel je faisais référence précédemment: vous ne remarqueriez rien, vous perdez simplement quelques lignes.
Ma recommandation est d'éviter d'attraper (mais pas de lever!) Des exceptions dans le code où produire une sortie incorrecte est pire que sortir. La seule fois où j'attrape une exception dans un tel code, c'est lorsque j'ai une expression vraiment triviale. Je peux donc facilement déterminer la cause de chacun des types d'exception possibles.
En ce qui concerne l'impact sur les performances de l'utilisation des exceptions, il est trivial (en Python), à moins que des exceptions ne soient rencontrées fréquemment.
Si vous utilisez des exceptions pour gérer des conditions courantes, vous pouvez parfois payer un coût de performances énorme. Par exemple, supposons que vous exécutiez une commande à distance. Vous pouvez vérifier que le texte de votre commande passe au moins la validation minimale (par exemple, la syntaxe). Vous pouvez également attendre qu'une exception soit déclenchée (ce qui ne se produit qu'une fois que le serveur distant a analysé votre commande et a constaté un problème). De toute évidence, le premier est beaucoup plus rapide. Autre exemple simple: vous pouvez vérifier si un nombre est égal à zéro ~ 10 fois plus rapidement que d'essayer d'exécuter la division puis d'attraper l'exception ZeroDivisionError.
Ces considérations importent uniquement si vous envoyez fréquemment des chaînes de commandes mal formées à des serveurs distants ou si vous recevez des arguments de valeur zéro que vous utilisez pour la division.
Note: Je suppose que vous utiliseriez à la except ValueError
place du juste except
; comme d'autres l'ont fait remarquer, et comme le livre lui-même l'indique en quelques pages, il ne faut jamais utiliser nu except
.
Autre remarque: l'approche appropriée sans exception consiste à compter le nombre de valeurs renvoyées par split
plutôt qu'à la recherche :
. Ce dernier est beaucoup trop lent, car il répète le travail effectué split
et peut presque doubler le temps d'exécution.