Apprenez en lisant dans l'ordre

Attraper les exceptions avec try / except

Apprends à gérer les exceptions en Python avec try / except / finally pour rendre ton programme robuste face aux erreurs.

try / except est le mécanisme qui attrape les erreurs levées à l'exécution et garde ton programme en marche au lieu de le laisser planter. Utilise-le pour les opérations qui peuvent échouer de temps en temps — récupération de données externes, validation de saisie utilisateur, opérations sur les fichiers, etc.

Erreurs de syntaxe vs. erreurs d'exécution

Python a deux grandes familles d'erreurs. Les erreurs de syntaxe surviennent quand le code viole la grammaire de Python et sont détectées avant que le programme ne s'exécute. Les erreurs d'exécution (exceptions) sont grammaticalement correctes mais apparaissent pendant que le programme tourne. Seules les erreurs d'exécution peuvent être attrapées avec try / except.

Erreurs de syntaxe vs. erreurs d'exécution
Erreur PythonErreur de syntaxe(avant exécution)Erreur d'exécution(levée à l'exécution)Programme ne démarre pastry ne peut pas l'attraperPeut être attrapéeavec try / exceptdeux-points manquantsdivision par zéro

Les erreurs de syntaxe sont détectées au moment où Python lit le code, donc le programme ne démarre jamais. Les erreurs d'exécution ne se déclenchent que quand l'exécution atteint réellement cette ligne — c'est pour ça que try / except peut les intercepter.

# Erreur de syntaxe : deux-points manquants. Échoue avant même l'exécution de la ligne
# if x > 0
#     print("positif")

# Erreur d'exécution : grammaticalement correcte, mais échoue à l'exécution
x = 100
print(x / 0)   # ZeroDivisionError: division by zero
print("cette ligne ne s'exécute jamais")

Quand une erreur d'exécution est levée, tout ce qui suit cette ligne est sauté. Exécute le prochain extrait et tu verras que le print() final ne se déclenche pas — le programme s'arrête à IndexError.

# Confirmation d'une erreur d'exécution : sans try, le programme s'arrête
numbers = [10, 20, 30]
print(numbers[10])       # IndexError: list index out of range
print("cette ligne ne s'exécute jamais")
# Sortie :
# Traceback (most recent call last):
#   File "...", line 3, in <module>
# IndexError: list index out of range

Les bases de try / except

Mets le code risqué dans le bloc try: et le code de récupération dans un bloc except ClasseErreur:.

Dès qu'une erreur se déclenche dans try, le reste du corps de try est sauté et le contrôle saute vers l'except correspondant. Le code après except continue de s'exécuter même quand une erreur survient.

Comment try / except s'enchaîne
exécute le corps de tryune erreur s'est levée ?pas d'erreur(exécuté jusqu'au bout)erreur levée(reste sauté)except est sautéexécute l'exceptcorrespondantcontinue avec la suiteNonOuimatch

Exécute le corps de try. Si aucune exception n'est levée, l'except est sauté et le contrôle passe au reste du programme. Si une exception se déclenche, le reste du corps de try est sauté, l'except correspondant s'exécute, puis le contrôle continue.

# Envelopper dans try garde le programme en marche même quand la division par zéro se déclenche
a = 100
try:
    result = a / 0
    print(result)              # jamais atteint
except ZeroDivisionError:
    print("Division par 0 impossible")  # le contrôle saute ici

print("après le bloc try")     # s'exécute toujours après try / except
# Sortie : Division par 0 impossible
#         après le bloc try

Protège l'accès à un index hors plage dans une liste de stock.

① Définis stock = [12, 8, 3] (quantité sur chaque étagère).

② Confirme d'abord ce qui se passe si tu appelles stock[5] sans try. La réponse garde cette ligne en commentaire ; décommente-la pour voir le programme s'arrêter avec IndexError.

③ Maintenant exécute print(stock[5]) à l'intérieur de try et affiche "Cette étagère n'existe pas" depuis except IndexError:.

④ Après try / except, affiche "Poursuite…" pour confirmer que l'exécution reprend même après l'exception.

(L'explication apparaît une fois que tu auras exécuté le code correctement.)

Éditeur Python

Exécuter le code pour voir le résultat

Capturer l'objet exception avec as e

Écrire except ClasseErreur as e: met les détails de l'exception dans e. print(e) affiche le message d'erreur, et type(e) affiche la classe d'erreur. Les logger est un bon point de départ pour tracer les problèmes plus tard.

user_input = "abc"   # censé être un nombre, mais une chaîne est arrivée

try:
    value = int(user_input)
except ValueError as e:
    print("La saisie n'est pas numérique")
    print(f"Détails : {e}")
    print(f"Type : {type(e).__name__}")
# Sortie : La saisie n'est pas numérique
#         Détails : invalid literal for int() with base 10: 'abc'
#         Type : ValueError
Ce que tu peux extraire de l'objet exception
erreur se déclencheint("abc")except ValueError as eobjet exception estr(e)→ messagetype(e).__name__→ nom de classetraceback.format_exc()→ traceaffecte

Le message seul ne te dit pas l'erreur a été levée, donc pendant le debug, le standard est de l'associer à import traceback. traceback.format_exc() renvoie le chemin d'appel (traceback) au moment où l'exception s'est déclenchée, et le logger rend l'analyse de cause racine bien plus facile.

import traceback

try:
    value = int("abc")
except ValueError as e:
    print(f"Détails : {e}")
    print(f"Type : {type(e).__name__}")
    print("--- traceback ---")
    print(traceback.format_exc())
# Sortie :
# Détails : invalid literal for int() with base 10: 'abc'
# Type : ValueError
# --- traceback ---
# Traceback (most recent call last):
#   File "...", line 4, in <module>
#     value = int("abc")
# ValueError: invalid literal for int() with base 10: 'abc'

Quand la saisie utilisateur ne peut pas être convertie en nombre, affiche le message, le type et la trace d'appels ensemble.

① En haut, écris import traceback et mets user_input = "Paris".

② Dans try, appelle int(user_input), et attrape avec except ValueError as e:.

③ Dans except, affiche "Message : {e} / Type : {type(e).__name__}" sur une ligne, puis print(traceback.format_exc()).

Éditeur Python

Exécuter le code pour voir le résultat

Plusieurs blocs except et le filet Exception

Tu peux empiler plusieurs blocs except sur un seul try. Celui qui match en premier s'exécute, donc l'idiome est de les lister du plus spécifique au plus général.

Toute erreur d'exécution hérite de Exception, donc except Exception as e: attrape tout, y compris les erreurs inattendues.

Ordonne except du spécifique au général
erreur dans corps tryexceptIndexError ?exécute handlerIndexErrorexceptZeroDivisionError ?exécute handlerZeroDivisionErrorexceptException ?filet pourinattenducontinueaprès trymatchpas de matchmatchpas de matchmatch
numbers = [10, 20, 30]
index = 1
divisor = 0

try:
    value = numbers[index]
    print(value / divisor)
except IndexError as e:
    print(f"Index hors plage : {e}")
except ZeroDivisionError as e:
    print(f"Division par 0 impossible : {e}")
except Exception as e:
    print(f"Autre erreur : {type(e).__name__}: {e}")
# Sortie : Division par 0 impossible : division by zero

Ne mets pas Exception en premier

Exception est le parent de quasiment toutes les exceptions, donc le placer en haut empêche tout except plus spécifique qui suit de s'exécuter. Utilise-le comme dernier filet de sécurité pour les erreurs inattendues.

Extraire un certain nombre d'éléments de l'historique d'achats d'un utilisateur, les sommer et calculer la moyenne.

① Définis history = [1200, 800, 1500] (montants d'achat) et take = 10 (nombre à prendre).

② Dans try, calcule total = sum(history[:take]), puis avg = total / len(history[:take]) et print(f"Moyenne : {avg}").

③ Ajoute un filet : except ZeroDivisionError as e: affiche "Pas de données", et except Exception as e: affiche "Inattendu : {e}". (Sur le chemin heureux, la moyenne s'affiche normalement.)

Éditeur Python

Exécuter le code pour voir le résultat

Exécuter le nettoyage avec finally

Le bloc finally: est la case de nettoyage qui s'exécute toujours, qu'une exception se déclenche ou non. Utilise-le pour libérer les ressources qui doivent être fermées — fichiers, connexions DB, etc.

Le bloc else: s'exécute seulement quand aucune exception n'a été levée. Il n'est pas utilisé aussi souvent, mais il rend explicite le chemin « seulement en cas de succès, on continue ».

Ordre d'exécution de try / except / else / finally
exécute le corps de tryune exceptions'est levée ?bloc else(succès seulement)bloc except(gère-la)bloc finally(toujours exécuté)continue avec la suiteNon (succès)Oui (échec)

Après l'exécution de try : pas d'exception → va dans else, exception → va dans l'except correspondant. Dans les deux cas, finally s'exécute toujours à la fin — c'est la clé.

# Chemin heureux : else et finally s'exécutent
a, b = 10, 2
try:
    result = a / b
except ZeroDivisionError:
    print("Division par zéro attrapée")
else:
    print(f"Succès : {result}")
finally:
    print("Exécution du nettoyage")
# Sortie : Succès : 5.0
#         Exécution du nettoyage

print("---")

# Chemin d'erreur : except et finally s'exécutent
a, b = 10, 0
try:
    result = a / b
except ZeroDivisionError:
    print("Division par zéro attrapée")
else:
    print(f"Succès : {result}")
finally:
    print("Exécution du nettoyage")
# Sortie : Division par zéro attrapée
#         Exécution du nettoyage

Simule un appel API et loggue succès, échec et nettoyage sur chaque chemin.

① Définis user_ids = [101, 102, 103] et target = 0.

② Dans try, récupère user = user_ids[target] (n'affiche pas encore).

③ Dans except IndexError:, affiche "Pas d'utilisateur".

④ Dans else:, affiche f"Récupéré : {user}" pour que ça s'exécute seulement quand aucune exception ne s'est déclenchée.

⑤ Dans finally:, affiche "Connexion fermée" pour que ça s'exécute dans les deux cas.

Éditeur Python

Exécuter le code pour voir le résultat

Dans cet article, tu as appris les bases de la gestion des exceptions avec try / except, comment capturer les infos d'exception avec as e, comment empiler plusieurs blocs except et utiliser Exception comme filet, et comment exécuter le nettoyage avec finally. Prochaine étape : lever toi-même des exceptions avec raise, et définir des classes d'exceptions personnalisées.

QUIZ

Vérification des connaissances

Répondez à chaque question une par une.

Question 1Laquelle de celles-ci est un exemple d'erreur de syntaxe ?

Question 2Qu'affiche le code suivant ?
a = 100
try:
print(a / 0)
except ZeroDivisionError:
print("attrapé")
print("fin")

Question 3Parmi try / except / else / finally, lequel s'exécute toujours, qu'une exception ait été levée ou non ?