Menu
Français

Exceptions Python : try, except, else, finally et raise

Comment gérer les erreurs en Python — try/except/finally, attraper des exceptions spécifiques, lever les tiennes, et quand laisser une erreur se propager.

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

main.py
Output
Click Run to see the output here.
  • try: ouvre le bloc de code risqué.
  • except ValueError: attrape cette exception spécifique si elle est levée dans le try.
  • Si aucune exception ne se déclenche, le except est 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 :

main.py
Output
Click Run to see the output here.

Tu peux attraper plusieurs exceptions dans une seule clause en passant un tuple :

main.py
Output
Click Run to see the output here.

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 :

  • else s'exécute si le bloc try s'est terminé sans lever.
  • finally s'exécute quoi qu'il arrive — exception ou non.
main.py
Output
Click Run to see the output here.

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 :

main.py
Output
Click Run to see the output here.

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 :

main.py
Output
Click Run to see the output here.

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 :

main.py
Output
Click Run to see the output here.

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/except te permet de gérer les erreurs que tu peux récupérer.
  • Attrape des exceptions spécifiques, pas Exception en bloc.
  • raise signale des erreurs dans ton propre code.
  • Les blocs with remplacent la plupart des nettoyages avec finally.
  • 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.

Apprendre à coder avec Coddy

COMMENCER