🚨python

Gerer les exceptions en Python : try except finally

30 mars 2026 5 min de lecture

Pourquoi gérer les exceptions ? De l'erreur qui plante au programme robuste

Tu as sûrement déjà vu ce message redouté : Traceback (most recent call last): ... ZeroDivisionError: division by zero. Ton programme s'arrête net, l'utilisateur est perdu. C'est ça, une exception non gérée. En NSI, et dans la vraie vie d'un développeur, un bon programme n'est pas seulement un programme qui fonctionne quand tout va bien, mais un programme qui sait réagir quand les choses tournent mal. La gestion des exceptions, c'est l'art d'anticiper les problèmes pour offrir une expérience fluide. Imagine une calculatrice qui plante si tu divises par zéro au lieu d'afficher un message clair. C'est la différence entre un script de débutant et un projet professionnel.

La structure de base : try et except

Le bloc try...except est le cœur de la gestion des erreurs. Son principe est simple : tu essaies d'exécuter du code dans le bloc try. Si une erreur survient, Python saute directement dans le bloc except au lieu de planter.

Un exemple concret

Prenons un cas classique : la conversion d'une saisie utilisateur.

# Sans gestion d'erreur
age = int(input("Quel est ton âge ? "))
print(f"Tu as {age} ans.")
# Si l'utilisateur tape "dix-sept", c'est le crash ! ValueError.

Voici la version robuste :

try:
age = int(input("Quel est ton âge ? "))
print(f"Tu as {age} ans.")
except ValueError:
print("Attention ! Tu dois entrer un nombre entier.")

Ici, si la conversion en int échoue, Python exécute le code dans except ValueError. Le programme continue son exécution normalement après.

Capturer plusieurs types d'exceptions

Tu peux gérer différents types d'erreurs de manière spécifique :

try:
numerateur = int(input("Numérateur : "))
denominateur = int(input("Dénominateur : "))
resultat = numerateur / denominateur
print(f"Résultat : {resultat}")
except ValueError:
print("Erreur : tu dois saisir des nombres.")
except ZeroDivisionError:
print("Erreur : division par zéro impossible.")

Tu peux aussi capturer toutes les exceptions (à utiliser avec prudence) avec un except général ou en capturant la classe mère Exception.

Aller plus loin : else et finally

La structure complète offre deux blocs optionnels très puissants : else et finally.

Le bloc else : exécuté seulement en cas de succès

Le code dans else ne s'exécute que si aucune exception n'a été levée dans le try. C'est parfait pour le code qui dépend du succès du bloc try, mais qui ne doit pas lui-même être protégé des mêmes exceptions.

try:
fichier = open("donnees.txt", "r")
contenu = fichier.read()
except FileNotFoundError:
print("Le fichier est introuvable.")
else:
# Ce code n'est exécuté que si l'ouverture a réussi.
print("Fichier lu avec succès.")
print(f"Taille : {len(contenu)} caractères.")
fichier.close() # On ferme le fichier ici.

Le bloc finally : le nettoyage garanti

Le bloc finally est toujours exécuté, qu'une exception ait été levée ou non, et même si un return ou un break intervient. C'est l'endroit idéal pour les actions de « nettoyage » qui doivent absolument avoir lieu, comme fermer un fichier ou une connexion réseau.

try:
fichier = open("config.txt", "r")
# Traitement qui pourrait planter...
donnees = fichier.read()
resultat = int(donnees) * 2
except (FileNotFoundError, ValueError) as e:
print(f"Problème avec le fichier ou son contenu : {e}")
finally:
# Cette ligne sera exécutée dans TOUS les cas.
print("Tentative de fermeture du fichier.")
fichier.close()

Même si une erreur survient pendant le traitement, le fichier sera fermé, évitant ainsi des fuites de ressources.

Lever et créer ses propres exceptions

Parfois, c'est toi qui dois signaler qu'une erreur s'est produite. Pour cela, on utilise le mot-clé raise.

Lever une exception existante

Imaginons une fonction qui calcule la racine carrée d'un nombre, mais seulement pour les nombres positifs dans notre contexte.

def ma_racine_carree(x):
if x < 0:
raise ValueError("Le nombre doit être positif ou nul.")
return x ** 0.5

try:
print(ma_racine_carree(-4))
except ValueError as erreur:
print(erreur) # Affiche : Le nombre doit être positif ou nul.

Créer sa propre classe d'exception

Pour des erreurs métier spécifiques à ton projet NSI, tu peux définir tes propres classes. Il suffit qu'elles héritent (directement ou indirectement) de la classe Exception.

class ErreurNoteInvalide(Exception):
"""Exception levée pour une note en dehors de l'intervalle 0-20."""
pass

def ajouter_note(note):
if not 0 <= note <= 20:
raise ErreurNoteInvalide(f"La note {note} n'est pas entre 0 et 20.")
# ... traitement de la note ...

try:
ajouter_note(25)
except ErreurNoteInvalide as e:
print(f"Erreur de saisie : {e}")

Cela rend ton code beaucoup plus clair et facile à déboguer.

Bonnes pratiques et pièges à éviter

Ne pas abuser de l'except général : except: ou except Exception: sans préciser le type d'erreur peut masquer des bugs inattendus. Attrape des exceptions spécifiques.

Éviter les blocs try vides ou trop larges : Mets dans le try uniquement le code qui peut générer l'erreur que tu veux capturer.

Donner des messages d'erreur utiles : Pour l'utilisateur ou pour toi-même lors du débogage. Utilise as e pour accéder au message de l'exception.

Structure recommandée pour un code propre :

  • try : Le code à risque.
  • except : Gestion spécifique des erreurs connues.
  • else : Code à exécuter en cas de succès.
  • finally : Code de nettoyage (fermeture de ressources).

En maîtrisant try, except, else et finally, tu fais un pas de géant vers la création de programmes solides et professionnels, une compétence essentielle pour ton projet de NSI et au-delà.

📚 Pour aller plus loin

Questions fréquentes

Quelle est la différence entre une erreur de syntaxe et une exception ?

Une erreur de syntaxe (comme un `print` mal orthographié) empêche ton code de s'exécuter du tout. Python ne peut même pas le lire. Une exception (comme `ZeroDivisionError`) se produit pendant l'exécution du code, quand une instruction valide rencontre un problème (comme diviser par zéro). Les exceptions, elles, peuvent être gérées avec `try...except`.

Quand dois-je utiliser `finally` plutôt que de mettre du code après le bloc `try...except` ?

Le bloc `finally` est exécuté dans **tous les cas**, même si une exception n'est pas attrapée par un `except`, ou si tu utilises `return`, `break` ou `continue` dans le bloc `try` ou `except`. Le code placé simplement après le bloc `try...except` ne serait pas exécuté dans ces situations. Utilise `finally` pour les actions critiques comme fermer un fichier ou une connexion réseau qui doit absolument avoir lieu.

Est-ce une bonne pratique d'utiliser `except:` sans préciser le type d'exception ?

Non, c'est généralement une mauvaise pratique. Capturer toutes les exceptions de manière silencieuse peut masquer des bugs inattendus dans ton code (comme des `NameError` dus à une faute de frappe) et les rendre très difficiles à déboguer. Utilise toujours des exceptions spécifiques (comme `ValueError`, `FileNotFoundError`) ou, au pire, `except Exception as e:` pour au moins pouvoir logger l'erreur.

Comment choisir le type d'exception à lever avec `raise` ?

Choisis l'exception intégrée la plus appropriée au problème. Par exemple, utilise `ValueError` pour un argument de fonction qui a un type correct mais une valeur inappropriée (un âge négatif). `TypeError` si le type est incorrect. `FileNotFoundError` si un fichier est manquant. Si aucune exception standard ne correspond bien, crée ta propre classe comme expliqué dans l'article.

Bravo ! Tu as lu cet article
Inscris-toi pour sauvegarder ta progression et gagner des XP
Creer mon compte
exceptions Pythontry except
Pixel