Question 1Laquelle de celles-ci est un exemple d'erreur de syntaxe ?
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.
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.
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
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
Le message seul ne te dit pas où 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'
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.
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.
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 ».
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
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.
Vérification des connaissances
Répondez à chaque question une par une.
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 ?