Un programme réel rencontre des imprévus : fichier manquant, saisie invalide, réseau coupé, division par zéro... La gestion des exceptions est le mécanisme Python pour réagir proprement à ces situations sans planter. C'est un savoir-faire essentiel dès le niveau Avancé du TOSA.
Qu'est-ce qu'une exception ?
Quand Python rencontre une erreur à l'exécution, il « lève » (raises) une exception. Sans gestion, le programme s'arrête immédiatement.
n = int("abc") # ValueError
print("Suite...") # jamais atteintChaque erreur appartient à un type (ValueError, TypeError, ZeroDivisionError...) et contient un message.
Les exceptions les plus courantes
| Exception | Cause typique |
|---|---|
SyntaxError |
Erreur de syntaxe (détectée avant exécution) |
NameError |
Variable non définie |
TypeError |
Opération entre types incompatibles |
ValueError |
Type correct, valeur invalide (int("abc")) |
ZeroDivisionError |
Division par zéro |
IndexError |
Indice hors limites dans une séquence |
KeyError |
Clé absente dans un dict |
FileNotFoundError |
Fichier introuvable |
AttributeError |
Attribut inexistant sur un objet |
ImportError / ModuleNotFoundError |
Module introuvable |
try / except : intercepter une exception
La structure de base :
try:
# code risqué
except TypeErreur:
# que faire si TypeErreur arrivePremier exemple
try:
n = int("abc")
except ValueError:
print("Ce n'est pas un entier valide !")
print("Le programme continue.")Le programme ne plante pas. Python saute dans le except, puis reprend son cours.
Récupérer le message de l'erreur
Avec as e on récupère l'objet exception, notamment pour accéder à son message.
try:
n = int("abc")
except ValueError as e:
print(f"Erreur : {e}")Attraper plusieurs types différents
valeurs = ["10", "abc", None]
for v in valeurs:
try:
n = int(v)
print(f"OK : {n}")
except ValueError:
print(f"Valeur invalide : {v!r}")
except TypeError:
print(f"Type invalide : {v!r}")On peut aussi grouper plusieurs exceptions en un seul except avec un tuple :
valeurs = ["10", "abc", None]
for v in valeurs:
try:
n = int(v)
print(f"OK : {n}")
except (ValueError, TypeError) as e:
print(f"Problème avec {v!r} : {e}")Le pattern EAFP vs LBYL
Python a une philosophie particulière : « il est plus facile de demander pardon que la permission » (Easier to Ask Forgiveness than Permission, EAFP).
LBYL : « Look Before You Leap »
Vérifier avant d'agir — typique des autres langages.
d = {"a": 1, "b": 2}
# LBYL : on vérifie avant
if "c" in d:
print(d["c"])
else:
print("Clé absente")EAFP : « Easier to Ask Forgiveness »
Essayer, et rattraper en cas d'erreur.
d = {"a": 1, "b": 2}
# EAFP : on tente, on rattrape
try:
print(d["c"])
except KeyError:
print("Clé absente")else et finally
Un bloc try peut inclure jusqu'à 4 clauses : try, except, else, finally.
else — exécuté si aucune exception n'a été levée
def diviser(a, b):
try:
resultat = a / b
except ZeroDivisionError:
print("Division par zéro !")
else:
print(f"Résultat : {resultat}")
diviser(10, 2) # else exécuté
diviser(10, 0) # except exécuté, else nonPourquoi un else ? Pour séparer clairement ce qu'on protège (dans try) de ce qu'on fait ensuite (dans else). Évite d'attraper accidentellement une exception venue du code post-opération.
finally — toujours exécuté
def diviser(a, b):
try:
resultat = a / b
except ZeroDivisionError:
print("Division par zéro")
return None
else:
return resultat
finally:
print("Nettoyage (toujours exécuté)")
print(diviser(10, 2))
print("---")
print(diviser(10, 0))finally sert au nettoyage : fermer un fichier, libérer une ressource, déconnecter une base de données... Il s'exécute quoi qu'il arrive, même en cas de return ou d'exception non attrapée.
Structure complète
try:
# code risqué
except TypeErreur1:
# gestion spécifique
except TypeErreur2:
# autre gestion
else:
# si aucune exception n'est levée
finally:
# toujours exécuté