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 🚨
| Erreur | Description | Exemple |
|---|---|---|
SyntaxError | Erreur de syntaxe | if True print("ok") |
NameError | Variable inexistante | print(variable_inconnue) |
TypeError | Type inapproprie | "hello" + 5 |
ValueError | Valeur inappropriate | int("bonjour") |
IndexError | Index hors limites | [1,2,3][5] |
KeyError | Cle absente d'un dict | {"a": 1}["b"] |
FileNotFoundError | Fichier introuvable | open("x.txt") |
ZeroDivisionError | Division par zero | 10 / 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
trycontient le code "risque". Si une erreur survient, le programme saute directement au blocexceptcorrespondant.
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")
| Bloc | S'execute quand ? |
|---|---|
try | Toujours |
except | Si une erreur survient |
else | Si aucune erreur |
finally | Toujours, 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 ete 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/5Le bloc try permet de tester du code qui pourrait lever une exception. Python va essayer d'exécuter le code du bloc.