La gestion des exceptions en Python

@joekakone

Joseph Konka @joekakone

03/03/2026 · 10 min

Rendez vos programmes robustes et tolérants aux pannes grâce aux blocs try, except, else et finally. Maîtrisez la philosophie EAFP, le déclenchement d'erreurs avec raise et la création d'exceptions personnalisées.

La gestion des exceptions en langage Python#

En informatique, même un code rédigé sans aucune erreur de syntaxe peut subir des anomalies imprévues lors de son exécution : un utilisateur qui saisit des lettres à la place d'un âge, un fichier manquant sur le disque dur, un réseau défaillant ou une tentative de division par zéro.

Sans mécanisme de protection, ces anomalies provoquent l'interruption brutale du programme (crash) et affichent une trace d'erreur (Traceback) intimidante pour l'utilisateur. En Python, la gestion professionnelle des erreurs s'effectue via le mécanisme des exceptions.


1. La philosophie Python : EAFP contre LBYL#

Dans la plupart des langages traditionnels (comme le C), on adopte l'approche LBYL (Look Before You Leap — « Regarde avant de sauter ») en multipliant les vérifications préventives préalables avec des if.

En Python, la communauté privilégie la philosophie EAFP (Easier to Ask for Forgiveness than Permission — « Il est plus facile de demander pardon que la permission »). On tente d'exécuter l'action directement dans un bloc try, et si un incident survient, on l'intercepte proprement dans un bloc except.

# Approche LBYL (Vérification préalable lourde) :
if saisie.isdigit():
    nombre = int(saisie)
else:
    print("Saisie non numerique.")

# Approche EAFP (Recommandée et Pythonique) :
try:
    nombre = int(saisie)
except ValueError:
    print("Saisie non numerique.")

2. La structure complète : try, except, else, finally#

L'instruction de gestion des exceptions peut comporter jusqu'à quatre clauses complémentaires :

flowchart TD
    A[Bloc try : Code à exécuter] -->|Erreur levée| B[Bloc except : Traitement de l'erreur]
    A -->|Aucune erreur| C[Bloc else : Traitement nominal]
    B --> D[Bloc finally : Nettoyage systématique]
    C --> D
Bloc Déclenchement Rôle
try Toujours Encapsule les instructions susceptibles de lever une exception
except ExceptionType as err Si l'erreur ciblée se produit Intercepte l'erreur, empêche le plantage et traite l'anomalie
else Seulement si aucune erreur n'est survenue dans try Exécute la suite du traitement nominal en toute sécurité
finally TOUJOURS (qu'il y ait eu erreur ou non) Libère les ressources (fermer un fichier, déconnecter une base)

Exemple complet#

def diviser_nombres(a_str: str, b_str: str) -> None:
    try:
        a = float(a_str)
        b = float(b_str)
        resultat = a / b
    except ValueError as err:
        print(f"Erreur de format : Vous devez saisir des nombres valides ({err}).")
    except ZeroDivisionError:
        print("Erreur arithmetique : La division par zero est impossible.")
    else:
        print(f"Succes : {a} / {b} = {resultat:.4f}")
    finally:
        print("Fin de l'operation de calcul.\n")

# Tests de différents scénarios :
diviser_nombres("10", "2")   # Cas nominal -> try, else, finally
diviser_nombres("10", "0")   # ZeroDivisionError -> try, except, finally
diviser_nombres("dix", "2")  # ValueError -> try, except, finally

3. Les exceptions courantes de la bibliothèque standard#

Toutes les exceptions en Python dérivent de la classe de base BaseException. Voici les plus fréquentes que vous rencontrerez quotidiennement :

Exception Cause courante Exemple déclencheur
ValueError Valeur incorrecte passée à une fonction valide int("bonjour")
TypeError Opération sur des types incompatibles "Score: " + 10
ZeroDivisionError Deuxième opérande d'une division égal à zéro 42 / 0
IndexError Tentative d'accès à un indice hors des limites d'une liste [1, 2][5]
KeyError Clé inexistante demandée dans un dictionnaire {"nom": "Bob"}["age"]
FileNotFoundError Tentative d'ouverture d'un fichier inexistant open("inexistant.txt")
KeyboardInterrupt L'utilisateur appuie sur Ctrl + C dans la console Interruption manuelle

[!CAUTION] Anti-pattern à bannir : N'écrivez JAMAIS de clause except: vide ou de clause générique except Exception: sans raison valable !
Une clause except: attrape absolument tout silencieusement, y compris les fautes de frappe dans vos variables et la combinaison Ctrl + C, rendant le débogage de vos applications impossible. Ciblez toujours expressément les exceptions attendues.


4. Déclencher une exception : raise#

Vous pouvez volontairement lever une exception pour signaler qu'une règle métier n'est pas respectée à l'aide du mot-clé raise :

def calculer_racine_carree(nombre: float) -> float:
    if nombre < 0:
        raise ValueError(f"Impossible de calculer la racine d'un nombre negatif ({nombre}).")
    return nombre ** 0.5

try:
    print(calculer_racine_carree(-9))
except ValueError as e:
    print(f"Alerte : {e}")

5. Créer ses propres classes d'exceptions#

Dans les projets d'entreprise, il est courant de créer des exceptions personnalisées héritant de la classe Exception pour clarifier la logique métier :

class SoldeInsuffisantError(Exception):
    """Exception levee lorsqu'un retrait depasse le solde disponible."""
    pass

class CompteBancaire:
    def __init__(self, titulaire: str, solde_initial: float):
        self.titulaire = titulaire
        self.solde = solde_initial

    def retirer(self, montant: float) -> None:
        if montant > self.solde:
            raise SoldeInsuffisantError(
                f"Retrait de {montant} EUR refuse pour {self.titulaire} (Solde : {self.solde} EUR)"
            )
        self.solde -= montant
        print(f"Retrait de {montant} EUR effectue. Nouveau solde : {self.solde} EUR")

# Utilisation :
compte = CompteBancaire("Alice", 100.0)
try:
    compte.retirer(150.0)
except SoldeInsuffisantError as err:
    print(f"Incident bancaire : {err}")

6. Mise en pratique : Saisie numérique sécurisée en boucle#

Voici un patron de conception (design pattern) classique que vous utiliserez dans la quasi-totalité de vos scripts interactifs :

def demander_entier_positif(message_invite: str) -> int:
    """Force l'utilisateur à saisir un entier strictement positif."""
    while True:
        saisie = input(message_invite).strip()
        try:
            valeur = int(saisie)
            if valeur <= 0:
                print("Erreur : La valeur doit etre un entier strictement positif. Reessayez.")
                continue
            return valeur  # Valeur valide : on sort de la boucle et de la fonction
        except ValueError:
            print(f"Erreur : '{saisie}' n'est pas un nombre entier valide. Reessayez.")

# Test du module :
quantite = demander_entier_positif("Veuillez saisir le nombre d'articles a commander : ")
print(f"Quantite validee avec succes : {quantite} unites.")

7. Défi d'application#

Écrivez une fonction recuperer_element(liste, index, valeur_par_defaut=None) qui tente de retourner liste[index]. Si une exception IndexError ou TypeError survient, la fonction capture l'erreur et retourne valeur_par_defaut sans jamais interrompre le programme.

Commentaires

Inscrivez-vous à une formation complète

Voir le catalogue