0 XP
?
Python : de zéro à la maîtrise/Exceptions et gestion d'erreurs
Intermédiaire35 min25 XP

Objectifs de cette leçon

  • Utiliser try/except pour intercepter les erreurs
  • Lever des exceptions avec raise
  • Comprendre le bloc finally

Exceptions et gestion d'erreurs ⚠️

Pourquoi gerer les erreurs ? 🤔

Les erreurs sont inevitables en programmation. Un fichier peut ne pas exister, un utilisateur peut taper des donnees invalides. La gestion des erreurs permet au programme de continuer a fonctionner meme en cas de probleme.

💡 Sans gestion d'erreurs, la premiere erreur plantait ton programme. Avec les exceptions, tu peux anticiper et recuperer.


Les types d'erreurs 🚨

ErreurDescriptionExemple
SyntaxErrorErreur de syntaxeif True print("ok")
NameErrorVariable inexistanteprint(variable_inconnue)
TypeErrorType inapproprie"hello" + 5
ValueErrorValeur inappropriateint("bonjour")
IndexErrorIndex hors limites[1,2,3][5]
KeyErrorCle absente d'un dict{"a": 1}["b"]
FileNotFoundErrorFichier introuvableopen("x.txt")
ZeroDivisionErrorDivision par zero10 / 0

try / except — le piege a erreurs 🪤

try:
    nombre = int(input("Entrez un nombre : "))
    resultat = 100 / nombre
    print(f"100 / {nombre} = {resultat}")
except ValueError:
    print("❌ Ce n'est pas un nombre valide !")
except ZeroDivisionError:
    print("❌ On ne peut pas diviser par zero !")

🔍 Le bloc try contient le code "risque". Si une erreur survient, le programme saute directement au bloc except correspondant.


try / except / else / finally — la structure complete 🏗️

try:
    f = open("data.txt", "r")
    contenu = f.read()
except FileNotFoundError:
    print("Le fichier n'existe pas !")
except PermissionError:
    print("Pas la permission !")
else:
    print(f"Fichier lu : {len(contenu)} caracteres")
finally:
    print("Operation terminee")
BlocS'execute quand ?
tryToujours
exceptSi une erreur survient
elseSi aucune erreur
finallyToujours, erreurs ou pas

Capturer l'erreur 📋

try:
    x = int(input("Nombre : "))
    resultat = 100 / x
except ValueError as e:
    print(f"Erreur de valeur : {e}")
except ZeroDivisionError as e:
    print(f"Erreur de division : {e}")
except Exception as e:
    print(f"Erreur inattendue : {type(e).__name__}: {e}")

💡 as e te permet de voir le message d'erreur exact. C'est tres utile pour debugger.


Lever des exceptions avec raise 🚀

def set_age(age):
    if not isinstance(age, int):
        raise TypeError("L'age doit etre un entier")
    if age < 0 or age > 150:
        raise ValueError(f"Age invalide : {age}")
    return age

try:
    set_age(-5)
except ValueError as e:
    print(e)  # "Age invalide : -5"

Exceptions personnalisees 🎨

class SoldeInsuffisantError(Exception):
    def __init__(self, solde, montant):
        self.solde = solde
        self.montant = montant
        super().__init__(
            f"Solde insuffisant : {solde}e disponibles, {montant}e demandes"
        )

class Compte:
    def __init__(self, solde=0):
        self.solde = solde

    def retirer(self, montant):
        if montant > self.solde:
            raise SoldeInsuffisantError(self.solde, montant)
        self.solde -= montant
        return self.solde

compte = Compte(100)
try:
    compte.retirer(150)
except SoldeInsuffisantError as e:
    print(f"❌ {e}")
# ❌ Solde insuffisant : 100e disponibles, 150e demandes

Les assertions 🔍

def calculer_moyenne(notes):
    assert len(notes) > 0, "La liste ne peut pas etre vide"
    return sum(notes) / len(notes)

print(calculer_moyenne([12, 15, 18]))  # 15.0
# calculer_moyenne([]) → AssertionError

📌 Les assertions sont pour les bugs de programmation. Les exceptions sont pour les erreurs attendues.


Diagramme de flux d'erreur 🔄


Patterns utiles 🧩

Lire un fichier avec fallback

def lire_config(chemin):
    try:
        with open(chemin, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        print("Fichier introuvable, valeurs par defaut")
        return {"theme": "clair", "langue": "fr"}
    except json.JSONDecodeError:
        print("Fichier JSON invalide")
        return {"theme": "clair", "langue": "fr"}

Validation d'entree utilisateur

def demander_entier(message, min_val=None, max_val=None):
    while True:
        try:
            valeur = int(input(message))
            if min_val is not None and valeur < min_val:
                print(f"Minimum : {min_val}")
                continue
            if max_val is not None and valeur > max_val:
                print(f"Maximum : {max_val}")
                continue
            return valeur
        except ValueError:
            print("Veuillez entrer un nombre entier valide")

age = demander_entier("Votre age : ", min_val=0, max_val=150)

Pieges a eviter ⚠️

# 1. Attraper TOUT (trop large)
try:
    risky_code()
except:  # ❌ Attrape TOUT
    pass

# ✅ Mieux
try:
    risky_code()
except Exception:  # Attrape les erreurs "normales"
    pass

# 2. Ne rien faire dans le except
try:
    risky_code()
except ValueError:
    pass  # ❌ L'erreur disparait silencieusement !

# 3. Utiliser les exceptions pour le flux normal
try:
    valeur = dict["cle"]
except KeyError:
    valeur = "defaut"
# ✅ Mieux : utiliser .get()
valeur = dict.get("cle", "defaut")

Exercice pour toi 🎯

# Exercice 1 : Calculatrice securisee
def calculer():
    try:
        a = float(input("Nombre 1 : "))
        op = input("Operateur (+, -, *, /) : ")
        b = float(input("Nombre 2 : "))
        if op == "+": return a + b
        elif op == "-": return a - b
        elif op == "*": return a * b
        elif op == "/":
            if b == 0: raise ZeroDivisionError("Division par zero")
            return a / b
        else: raise ValueError(f"Operateur inconnu : {op}")
    except ValueError as e:
        return f"Erreur : {e}"
    except ZeroDivisionError as e:
        return f"Erreur : {e}"

# Exercice 2 : Exception personnalisee
class PasswordError(Exception):
    pass

def valider_mdp(mdp):
    if len(mdp) < 8:
        raise PasswordError("Trop court (minimum 8 caracteres)")
    if not any(c.isupper() for c in mdp):
        raise PasswordError("Il manque une majuscule")
    if not any(c.isdigit() for c in mdp):
        raise PasswordError("Il manque un chiffre")
    return True

try:
    valider_mdp("Abc12345")
    print("Mot de passe valide ✅")
except PasswordError as e:
    print(f"❌ {e}")

💡 Regle d'or : Gere les erreurs que tu prevois. Laisse planter le programme pour les erreurs inattendues ! 🔧

⚡ Simulateur — Exceptions

Étape 1/5
📝 Pseudo-code
1try:
2 x = 10 / 0
3except ZeroDivisionError:
4 print("Division par zéro !")
5except Exception as e:
6 print(f"Erreur: {e}")
7finally:
8 print("Toujours exécuté")
⚙️ Exécution
📦 Mémoire
Aucune variable
🔀 Flux d'exécution
try
3
Entrée dans try

Le bloc try permet de tester du code qui pourrait lever une exception. Python va essayer d'exécuter le code du bloc.