Les erreurs, c'est juste des valeurs avec une mauvaise attitude
Quand quelque chose tourne mal en Python — division par zéro, lecture d'un fichier manquant, parsing d'un mauvais nombre — le runtime crée un objet exception et commence à dérouler la pile d'appels jusqu'à ce que quelque chose l'attrape. Si rien ne le fait, ton programme se termine et affiche un traceback.
Les exceptions ne sont pas mauvaises en elles-mêmes. C'est la façon dont Python signale « je ne peux pas continuer avec cette opération ; voici pourquoi ». Ton boulot, c'est de décider, cas par cas, lesquelles tu sais récupérer et lesquelles tu devrais laisser remonter.
La forme de base
try:ouvre le bloc de code risqué.except ValueError:attrape cette exception spécifique si elle est levée dans letry.- Si aucune exception ne se déclenche, le
exceptest sauté entièrement.
Lance l'extrait avec 42 — ça marche. Lance-le avec hello — le handler s'exécute.
Attraper des exceptions spécifiques
Python a une hiérarchie de types d'exceptions. Quelques-unes que tu rencontreras souvent :
ValueError— une valeur était fausse d'une manière ou d'une autre (int("abc"), arguments hors plage).TypeError— le mauvais type a été utilisé ("hi" + 3).KeyError— une clé de dict n'a pas été trouvée.IndexError— un indice de séquence était hors plage.FileNotFoundError— un fichier n'existe pas.ZeroDivisionError— essayé de diviser par zéro.AttributeError— un objet n'a pas l'attribut demandé.
Attrape la spécifique que tu sais gérer :
Tu peux attraper plusieurs exceptions dans une seule clause en passant un tuple :
Remarque le as e. Ça lie l'objet exception à e pour que tu puisses inspecter son message ou ses attributs.
Évite d'attraper tout
Un except: nu attrape littéralement n'importe quoi, y compris KeyboardInterrupt (ton Ctrl-C) et les sorties système. Ne l'utilise pas.
except Exception: est un peu mieux, mais toujours dangereux — il avale des bugs que tu n'avais pas anticipés et cache la vraie source des problèmes :
# Ne fais pas ça sans une vraiment bonne raison.
try:
do_something()
except Exception:
pass
Le bon mouvement, c'est presque toujours d'attraper l'exception spécifique que tu sais récupérer. Si une exception à laquelle tu ne t'attendais pas atteint le sommet de ton programme, le traceback te dit exactement ce qui a mal tourné — c'est une fonctionnalité, pas un bug.
else et finally
L'instruction try a deux clauses optionnelles de plus :
elses'exécute si le bloctrys'est terminé sans lever.finallys'exécute quoi qu'il arrive — exception ou non.
else est l'endroit le plus propre pour du code « succès uniquement » — tu ne veux pas qu'un bloc try fasse plus que la partie qui peut vraiment échouer. finally sert au nettoyage qui doit tourner même si le try échoue : fermer une ressource, libérer un verrou, restaurer l'état.
Lever des exceptions toi-même
Utilise raise pour signaler une erreur dans ton propre code :
Choisis un type d'exception qui colle à ce qui a mal tourné. Utilise d'abord les intégrés — ValueError, TypeError, FileNotFoundError — avant de définir ta propre classe.
Définir ta propre exception
Quand les intégrés ne capturent pas le sens, définis une exception personnalisée :
Hérite de Exception (ou d'un intégré plus spécifique) et donne une docstring à la classe. C'est généralement tout ce qu'il faut. Les exceptions personnalisées laissent les appelants attraper juste l'erreur qui a du sens pour leur domaine.
raise ... from ... : exceptions chaînées
Quand une exception en déclenche une autre, garde la chaîne :
Le from e attache l'erreur originale. Quand le traceback s'affiche, Python montre les deux — le ConfigError qui a fait surface et le FileNotFoundError qui l'a causé. Ce genre de piste est inestimable pour déboguer.
Gestionnaires de contexte : la façon plus propre de nettoyer
finally va bien, mais pour des ressources comme des fichiers, un gestionnaire de contexte (ce qu'utilise with) est presque toujours meilleur :
# Version finally
f = open("data.txt")
try:
data = f.read()
finally:
f.close()
# Version with
with open("data.txt") as f:
data = f.read()
Les deux sont sûrs. La forme with est plus courte et s'applique automatiquement. Utilise finally seulement quand tu fais quelque chose que la bibliothèque standard n'enveloppe pas déjà dans un gestionnaire de contexte.
Quand ne pas attraper
Attraper une exception est une décision — tu dis « je peux gérer ça ». Si tu ne peux pas, laisse l'exception se propager. Du code comme ça est presque toujours une erreur :
try:
do_work()
except Exception:
pass # ignore tout silencieusement
Faire taire les erreurs rend les bugs invisibles. Il vaut mieux planter bruyamment que de continuer boiteux dans un état incohérent.
Récap
try/exceptte permet de gérer les erreurs que tu peux récupérer.- Attrape des exceptions spécifiques, pas
Exceptionen bloc. raisesignale des erreurs dans ton propre code.- Les blocs
withremplacent la plupart des nettoyages avecfinally. - Dans le doute, laisse l'exception se propager.
Ensuite : un tour des erreurs spécifiques que Python lève le plus souvent — KeyError, ValueError, ModuleNotFoundError, et quelques autres — plus les habitudes de débogage qui les corrigent vite.
Questions fréquentes
Comment gérer les erreurs en Python ?
Enveloppe du code risqué dans un bloc try et attrape l'exception spécifique dans un bloc except : try: risky() except ValueError: .... Un else optionnel s'exécute si aucune exception ne s'est produite ; finally s'exécute dans les deux cas, pour le nettoyage.
Dois-je attraper Exception pour être safe ?
Non. Un except: nu ou except Exception: cache des bugs que tu n'avais pas anticipés. Attrape l'exception spécifique que tu sais récupérer, et laisse le reste se propager pour que tu voies le vrai problème.
Quelle est la différence entre raise et raise from ?
raise NewError(...) lève une nouvelle exception. raise NewError(...) from original garde l'exception originale attachée comme cause, que Python montre dans le traceback. Utilise from quand une erreur de plus bas niveau a déclenché une de plus haut niveau que tu veux faire remonter.