Aller au contenu
M03 · C. Coder des solutions orientées objet

Administrer les exceptions

Distinguer les types d'erreurs, intercepter une exception avec try/except/else/finally, déclencher ses propres exceptions et lire la trace d'une erreur.

1Situer

L'application de la banque plante dès qu'un client tape « cent » au lieu de 100, ou quand il veut retirer plus que son solde. Le programme s'arrête net et le client voit un message incompréhensible. Une application professionnelle prévoit ces situations : elle intercepte l'erreur, affiche un message clair et continue à fonctionner.

2Comprendre

Une exception remonte jusqu'au try qui l'attrape
PILE DES APPELS programme principal try: traiter(op) traiter(op) c.retirer(3000) SoldeInsuffisant remonte... le programme continue

Le programme principal appelle traiter(), qui appelle c.retirer(3000). Les appels s'empilent.

1 / 5

Un programme rencontre trois sortes d’erreurs :

Type d’erreurQuandExemple
de syntaxeavant l’exécutiondeux-points oublié après un if
d’exécution (exception)pendant l’exécutiondivision par zéro, fichier absent
de logiquejamais signaléeune moyenne mal calculée

Les exceptions sont des objets : chaque type est une classe, et elles forment une hiérarchie qui part de Exception.

Les exceptions courantes

ValueError (valeur incorrecte, int("abc")), TypeError (mauvais type, "5" + 2), ZeroDivisionError, KeyError (clé absente d’un dictionnaire), IndexError (indice hors de la liste), FileNotFoundError, AttributeError.

Intercepter : try / except / else / finally

try:
    c.retirer(3000)              # le code risqué
except SoldeInsuffisant as e:     # si cette exception arrive
    print("Refusé :", e)
else:                             # si tout s'est bien passé
    print("OK")
finally:                          # dans tous les cas
    print("fin de l'opération")

On attrape les exceptions précises que l’on sait traiter. Un except: seul cache toutes les erreurs, y compris les bugs : à éviter.

Déclencher : raise

Une méthode qui ne peut pas faire son travail lève une exception : raise ValueError("le dépôt doit être positif"). Pour les règles de votre métier, créez votre propre classe d’exception, qui hérite de Exception.

La propagation et la trace

Une exception non interceptée remonte la pile des appels : de la méthode à la fonction qui l’a appelée, puis au programme principal. Si personne ne l’attrape, le programme s’arrête et affiche la trace (traceback). On la lit de bas en haut : type et message, puis la ligne et la fonction en cause.

Exemple simple

Le filet du trapéziste

Le trapéziste peut tomber ; le filet le rattrape et le spectacle continue. try, c'est le numéro risqué ; except, c'est le filet.

try:
    montant = int(input("Montant : "))
except ValueError:
    print("Merci de saisir un nombre")
Exemple simple

L'alarme incendie

Quand quelqu'un voit de la fumée, il déclenche l'alarme : ce n'est pas lui qui éteint le feu, ce sont les pompiers. raise déclenche l'alarme, le except qui l'attrape plus haut joue le rôle des pompiers.

if montant > solde:
    raise SoldeInsuffisant(montant, solde)

3Manipuler

Exécutez. Chaque opération qui échoue est interceptée, et le programme continue. Ajoutez une opération ("retirer", 5000), puis une opération ("deposer", "abc") et observez quelle exception est levée.
Pas à pas dans le lab ↗Python se charge au premier clic (environ 12 Mo, une seule fois).
Console
Mémoire : objets créés

Exécutez le code : les objets et leurs attributs s'afficheront ici.

4Pratiquer

Exercice 1 · La division sûre

Écrivez une fonction diviser(a, b) qui renvoie a / b, affiche « division par zéro » si b vaut 0 et « valeurs invalides » si a ou b ne sont pas des nombres.

Voir le corrigé
def diviser(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        print("division par zéro")
    except TypeError:
        print("valeurs invalides")

print(diviser(10, 2))
diviser(5, 0)
diviser("5", 2)

Exercice 2 · Une exception métier

Créez une exception NoteInvalide et faites-la lever par une méthode ajouter_note(note) quand la note n'est pas entre 0 et 20. Interceptez-la.

Voir le corrigé
class NoteInvalide(Exception):
    pass

class Stagiaire:
    def __init__(self):
        self.notes = []
    def ajouter_note(self, note):
        if not 0 <= note <= 20:
            raise NoteInvalide(f"{note} n'est pas entre 0 et 20")
        self.notes.append(note)

s = Stagiaire()
try:
    s.ajouter_note(25)
except NoteInvalide as e:
    print("Erreur :", e)

Exercice 3 · Lire une trace

Voici la fin d'une trace : « File "banque.py", line 18, in retirer / SoldeInsuffisant: retrait de 3000 DH impossible ». Où regarder en premier, et que faire ?

Voir le corrigé
On lit de bas en haut : la dernière ligne donne le type
(SoldeInsuffisant) et le message. La ligne au-dessus indique le
fichier (banque.py), la ligne (18) et la méthode (retirer).
Ici l'exception est voulue : il manque un try/except autour
de l'appel à retirer() pour afficher un message propre.

5Vérifier

1. Quand le bloc else d'un try s'exécute-t-il ?
2. Quelle instruction déclenche une exception ?
3. Comment crée-t-on son propre type d'exception ?