Comment gérer les exceptions en Python avec Try Except : Guide du débutant

Lors de l’écriture de code Python, il est quasiment inévitable de rencontrer des erreurs à l’exécution, que ce soit lors de la lecture d’un fichier, de l’analyse d’une entrée utilisateur ou de l’exécution de requêtes réseau. Une mauvaise gestion de ces erreurs peut entraîner des plantages frustrants pour les utilisateurs et rendant le débogage cauchemardesque. C’est là que la gestion des exceptions en Python devient une véritable bouée de sauvetage. Maîtriser try/except, else, finallyet les gestionnaires de contexte ( with) permet d’écrire du code résilient et plus propre, qui gère les problèmes avec élégance et détecte les bugs lorsqu’ils sont vraiment importants.

Ce guide abordera les bonnes pratiques essentielles pour gérer les exceptions en Python. Vous y trouverez des extraits de code concrets, des explications sur quand et pourquoi utiliser chaque approche, ainsi que des conseils qui pourraient vous éviter bien des soucis.À la fin, vous comprendrez comment ces techniques contribuent au bon fonctionnement de vos programmes, même en cas d’imprévu.

Comment gérer efficacement les exceptions en Python

Méthode 1 — Attraper des exceptions spécifiques (car attraper tout n’est pas toujours une bonne idée)

C’est la base d’une gestion efficace des erreurs. Au lieu de tout capturer avec un simple except, capturez uniquement les exceptions auxquelles vous êtes préparé. Cela permet d’éviter de masquer les bugs et facilite le débogage. Imaginons que vous lisiez une entrée utilisateur qui devrait être un nombre : la capture ValueErrorest logique.

raw = input("Enter a number: ") try: number = int(raw) print("You entered:", number) except ValueError: print("That wasn’t a valid number.") 

Dans certaines configurations, il est pratique d’intercepter plusieurs exceptions liées, surtout si la récupération est identique. Par exemple :

try: choice = ["apple", "pear", "banana"][int(raw)] except (ValueError, IndexError) as e: print("Invalid choice:", type(e).__name__) 

Les exceptions les plus courantes que vous rencontrerez incluent FileNotFoundError, ValueError, KeyError, etc. Savoir quand elles apparaissent est très utile, en particulier pendant le débogage.

Méthode 2 — Utilisation elseet finallypour une séparation propre

On oublie souvent que else« andfinally » Elsene s’exécute que si aucune erreur ne se produit ; c’est donc un bon endroit pour le code « réussi ».Finally« S’exécute toujours », parfait pour le nettoyage : fermeture de fichiers, libération de ressources, etc. C’est un peu étrange, mais dans certains cas, les deux sont nécessaires pour que tout soit bien rangé.

try: with open("config.json", "r", encoding="utf-8") as f: data = f.read() except FileNotFoundError: print("No config file found.") else: print("Loaded", len(data), "bytes.") 

Si vous souhaitez être particulièrement prudent, utilisez finallypour vous assurer que le fichier est fermé, même si une exception apparaît :

f = None try: f = open("config.json", "r", encoding="utf-8") data = f.read() except OSError as err: print("OS error:", err) finally: if f: f.close() 

Ce modèle est pratique car, dans certaines configurations, le withbloc peut ne pas fonctionner comme prévu, notamment lors de la gestion des ressources personnalisées. Gardez donc à l’esprit qu’il s’agit d’une solution de secours.

Méthode 3 — Enveloppez votre flux de travail principal dans un bloc de protection

Il est parfois utile d’avoir un système de détection d’erreurs de haut niveau, notamment pour détecter les bugs inattendus.

import logging, sys logging.basicConfig(level=logging. INFO) def main(): # core program code return 0 if __name__ == "__main__": try: code = main() except Exception: logging.exception("Unhandled error occurred") sys.exit(1) sys.exit(code) 

De cette façon, en cas de problème majeur, vous obtenez des journaux détaillés et le programme se termine avec un état différent de zéro, signalant l’échec aux outils d’automatisation ou aux scripts. Pratique, mais ne permettant pas d’ignorer les erreurs : c’est juste un filet de sécurité de dernier recours.

Méthode 4 — Exploiter les gestionnaires de contexte pour les ressources

Vous gérez des fichiers ou des sockets ? Utilisez-le, withcar il gère automatiquement le nettoyage. Par exemple :

from pathlib import Path try: with Path("data.txt").open("r", encoding="utf-8") as f: print(f.readline().strip()) except FileNotFoundError: print("Create data.txt first.") 

C’est bien plus propre que d’ouvrir et de fermer manuellement des fichiers, et cela réduit les risques de laisser un handle de fichier ouvert si une exception se produit au milieu de la lecture.

Méthode 5 — Lever, relancer et enchaîner les exceptions

Parfois, vous détectez une exception, mais souhaitez la relancer ou la contextualiser. Par exemple, si une vérification échoue :

def parse_age(s: str) -> int: if not s.isdigit(): raise ValueError("Age must contain only digits") age = int(s) if age < 0: raise ValueError("Age cannot be negative") return age 

Si vous détectez une erreur OSError mais décidez de la laisser se propager après la journalisation, la relance est la solution :

import logging try: do_risky_thing() except OSError as err: logging.error("OS error: %s", err) raise 

Les exceptions de chaîne fromsont pratiques lors du chargement de données ou de l’appel de modules :

from pathlib import Path import json def load_json(path: str): try: text = Path(path).read_text(encoding="utf-8") except OSError as e: raise RuntimeError(f"Failed to read {path}") from e return json.loads(text) 

Je ne sais pas pourquoi, mais cela permet de conserver les informations de traçage intactes, afin que vous puissiez voir ce qui s’est réellement mal passé.

Méthode 6 — Recueil d’erreurs inattendues (à utiliser avec parcimonie)

Si tout le reste échoue, vous pouvez utiliser une méthode plus large pour consigner les erreurs inhabituelles, mais n’en faites pas trop. Par exemple :

import traceback try: risky() except Exception as e: print(f"Unexpected {type(e).__name__}: {e}") traceback.print_exc() 

Soyez toutefois prudent lorsque vous interceptez BaseExceptiondes signaux d’arrêt du système, notamment ceux qui sont détectés. Ne le faites que si vous effectuez une procédure d’arrêt.

try: service_loop() except BaseException as e: print(f"Caught {type(e).__name__}; shutting down cleanly.") raise 

Méthode 7 — Gestion des erreurs multiples (Python 3.11+)

Si vous utilisez Python 3.11, ExceptionGroupcela facilite la gestion de plusieurs erreurs à la fois, en particulier lors du traitement par lots :

def run_tests(tests): errors = [] for t in tests: try: t.run() except Exception as e: e.add_note(f"Test {t.name} failed") errors.append(e) if errors: raise ExceptionGroup("Batch failures", errors) 

Et la capture de classes d’erreurs spécifiques except*permet un contrôle plus précis :

try: run_tests(tests) except* (ValueError, TypeError): print("Some data errors occurred.") except* OSError: print("Some OS errors occurred.") 

Conseils de dépannage courants

  • Erreurs d’analyse de nom — wrap int()ou float()in try/except ValueError.
  • Problèmes d’accès aux fichiers — catch FileNotFoundErrorou PermissionError.
  • Erreurs API ou réseau : gérez les délais d’expiration, les nouvelles tentatives et les connexions refusées.
  • Enregistrez toujours les exceptions : cela facilite grandement le débogage ultérieur.

Conclure

Bien gérer les exceptions ne consiste pas seulement à éviter les plantages : il s’agit d’écrire du code Python propre, maintenable et résilient. L’utilisation de catchs spécifiques, de gestionnaires de contexte et de gestionnaires de niveau supérieur garantit que votre application rebondit en cas de problème, au lieu de s’effondrer. Continuez à pratiquer ces techniques et bientôt, la gestion des erreurs ressemblera davantage à un filet de sécurité qu’à un casse-tête. Espérons que cela vous évitera quelques heures de réflexion !

Résumé

  • Capturez des exceptions spécifiques pour éviter de masquer les bugs.
  • Utilisez elseet finallypour un contrôle clair du flux et du nettoyage.
  • Tirez parti des gestionnaires de contexte pour la gestion des ressources.
  • Enveloppez les principaux flux de travail avec une gestion des erreurs de niveau supérieur.
  • Relancez et enchaînez les exceptions pour ajouter du contexte.
  • N’abusez pas des blocs fourre-tout larges : réfléchissez bien.
  • Dans Python 3.11+, à utiliser ExceptionGrouppour les erreurs de lot.