Exceptions
Anticipez et gérez les erreurs dans vos programmes
Gestion des exceptions en Python
Les exceptions sont des événements qui se produisent pendant l’exécution d’un programme et qui perturbent le flux normal d’instructions. En Python, les exceptions sont des objets qui représentent des erreurs. La gestion des exceptions est cruciale pour développer des applications robustes qui peuvent faire face à des situations imprévues sans planter.
Dans ce tutoriel, nous allons explorer comment identifier, gérer et créer des exceptions en Python.
Pourquoi gérer les exceptions ?
La gestion des exceptions est importante pour plusieurs raisons :
- Robustesse : Un programme qui gère correctement les exceptions peut continuer à fonctionner même lorsque des erreurs se produisent.
- Expérience utilisateur : Afficher des messages d’erreur conviviaux plutôt que des traces d’erreur techniques.
- Débogage : Obtenir des informations détaillées sur l’erreur pour faciliter la correction.
- Gestion des ressources : S’assurer que les ressources (fichiers, connexions réseau, etc.) sont correctement libérées, même en cas d’erreur.
Types d’exceptions courants en Python
Python comprend de nombreux types d’exceptions intégrés. Voici quelques-uns des plus courants :
SyntaxError
: Erreur dans la syntaxe du code.NameError
: Tentative d’utiliser une variable non définie.TypeError
: Opération ou fonction appliquée à un objet de type inapproprié.ValueError
: Opération ou fonction reçoit un argument du bon type mais avec une valeur inappropriée.IndexError
: Tentative d’accès à un index qui n’existe pas dans une séquence.KeyError
: Tentative d’accès à une clé qui n’existe pas dans un dictionnaire.FileNotFoundError
: Tentative d’ouverture d’un fichier qui n’existe pas.ZeroDivisionError
: Division par zéro.ImportError
: Échec lors de l’importation d’un module.IOError
: Erreur d’entrée/sortie (par exemple, lors de la lecture d’un fichier).AttributeError
: Tentative d’accès à un attribut inexistant.
Structure try-except-else-finally
Python utilise les blocs try
, except
, else
et finally
pour gérer les exceptions.
Structure de base try-except
try:
# Code susceptible de générer une exception
resultat = 10 / 0
except ZeroDivisionError:
# Code exécuté si une ZeroDivisionError se produit
print("Erreur : Division par zéro !")
Dans cet exemple, lorsque 10 / 0
génère une ZeroDivisionError
, le bloc except
correspondant est exécuté.
Capturer plusieurs types d’exceptions
Vous pouvez capturer différents types d’exceptions avec des gestionnaires distincts :
try:
# Code susceptible de générer des exceptions
nombre = int(input("Entrez un nombre : "))
resultat = 10 / nombre
except ValueError:
# Exécuté si l'entrée n'est pas un nombre valide
print("Erreur : Veuillez entrer un nombre valide.")
except ZeroDivisionError:
# Exécuté si nombre == 0
print("Erreur : La division par zéro n'est pas autorisée.")
Vous pouvez également capturer plusieurs exceptions avec le même gestionnaire :
try:
# Code susceptible de générer des exceptions
nombre = int(input("Entrez un nombre : "))
resultat = 10 / nombre
except (ValueError, ZeroDivisionError):
# Exécuté si l'une des exceptions mentionnées se produit
print("Erreur : Entrée invalide ou division par zéro.")
Capturer toutes les exceptions
Bien que ce ne soit généralement pas recommandé (car cela peut masquer des erreurs inattendues), vous pouvez capturer toutes les exceptions :
try:
# Code susceptible de générer n'importe quelle exception
# ...
except Exception as e:
# Exécuté pour toute exception qui hérite de Exception
print(f"Une erreur s'est produite : {e}")
Bloc else
Le bloc else
est exécuté si aucune exception n’est levée dans le bloc try
:
try:
nombre = int(input("Entrez un nombre : "))
resultat = 10 / nombre
except ValueError:
print("Entrée invalide.")
except ZeroDivisionError:
print("Division par zéro.")
else:
# Ce bloc est exécuté si aucune exception n'est levée
print(f"Le résultat est {resultat}")
Bloc finally
Le bloc finally
est exécuté quoi qu’il arrive, qu’une exception soit levée ou non :
try:
fichier = open("donnees.txt", "r")
# Opérations sur le fichier
except FileNotFoundError:
print("Le fichier n'existe pas.")
finally:
# Ce bloc est toujours exécuté
# Idéal pour libérer des ressources
if 'fichier' in locals():
fichier.close()
print("Fichier fermé.")
Le bloc finally
est particulièrement utile pour s’assurer que les ressources sont correctement libérées, même en cas d’erreur.
Lever des exceptions
Vous pouvez lever (ou “throw”) délibérément des exceptions en utilisant l’instruction raise
:
def diviser(a, b):
if b == 0:
raise ZeroDivisionError("Division par zéro non autorisée")
return a / b
try:
resultat = diviser(10, 0)
except ZeroDivisionError as e:
print(f"Erreur : {e}")
Créer des exceptions personnalisées
Vous pouvez créer vos propres types d’exceptions en héritant de la classe Exception
ou de l’une de ses sous-classes :
class ValeurNegativeError(Exception):
"""Exception levée lorsqu'une valeur négative est utilisée alors qu'elle ne devrait pas l'être."""
pass
def calculer_racine_carree(nombre):
if nombre < 0:
raise ValeurNegativeError("La racine carrée d'un nombre négatif n'est pas définie pour les nombres réels.")
import math
return math.sqrt(nombre)
try:
resultat = calculer_racine_carree(-1)
except ValeurNegativeError as e:
print(f"Erreur : {e}")
Assertions
Les assertions sont des vérifications de débogage qui testent si une condition est vraie. Si la condition est fausse, une exception AssertionError
est levée :
def diviser(a, b):
assert b != 0, "Le diviseur ne peut pas être zéro"
return a / b
try:
resultat = diviser(10, 0)
except AssertionError as e:
print(f"Assertion échouée : {e}")
Les assertions sont principalement utilisées pour le débogage et les tests, et peuvent être désactivées en mode de production.
Avec l’instruction with
L’instruction with
est utilisée pour garantir que les ressources sont correctement gérées, même en cas d’exception. C’est un moyen plus propre de gérer les exceptions pour les opérations qui nécessitent des ressources comme les fichiers :
try:
with open("fichier.txt", "r") as fichier:
contenu = fichier.read()
# Le fichier est automatiquement fermé à la fin du bloc with,
# même si une exception est levée
except FileNotFoundError:
print("Le fichier n'existe pas.")
Hiérarchie des exceptions
Les exceptions en Python forment une hiérarchie. Voici une partie simplifiée de cette hiérarchie :
BaseException
Exception
ArithmeticError
ZeroDivisionError
OverflowError
LookupError
IndexError
KeyError
OSError
FileNotFoundError
PermissionError
TypeError
ValueError
- …
SystemExit
KeyboardInterrupt
- …
Lorsque vous capturez des exceptions, l’ordre est important. Si vous avez plusieurs blocs except
, Python les vérifie dans l’ordre. Si une exception est une sous-classe d’une autre exception que vous avez déjà capturée, elle ne sera jamais atteinte :
try:
# Code susceptible de générer des exceptions
# ...
except Exception:
# Ce bloc attrapera toutes les exceptions qui héritent de Exception
print("Une exception s'est produite")
except ZeroDivisionError:
# Ce bloc ne sera JAMAIS atteint car ZeroDivisionError est une sous-classe de Exception
print("Division par zéro")
Pour éviter ce problème, placez les exceptions les plus spécifiques avant les plus générales.
Bonnes pratiques en matière de gestion des exceptions
-
Soyez spécifique : Capturez les exceptions spécifiques plutôt que d’utiliser un
except
générique. -
Ne pas supprimer les erreurs silencieusement : Évitez de capturer une exception sans la gérer correctement ou sans laisser une trace.
-
Utilisez
finally
pour le nettoyage : Utilisez le blocfinally
pour vous assurer que les ressources sont correctement libérées. -
Créez des exceptions personnalisées lorsque c’est approprié : Cela peut rendre votre code plus lisible et permettre une gestion plus fine des erreurs.
-
Conservez les blocs try petits : Ne mettez dans le bloc
try
que le code susceptible de générer l’exception. -
Logguez les exceptions : Dans les applications de production, pensez à enregistrer les exceptions dans des fichiers de log.
Conclusion
La gestion efficace des exceptions est une compétence essentielle pour tout programmeur Python. Elle vous permet d’écrire des programmes robustes qui peuvent gérer les erreurs de manière élégante.
Dans ce tutoriel, nous avons exploré comment identifier, capturer et lever des exceptions, comment créer vos propres types d’exceptions, et comment utiliser l’instruction with
pour gérer les ressources. Nous avons également discuté des bonnes pratiques pour une gestion efficace des exceptions.
Dans le prochain tutoriel, nous aborderons la manipulation de fichiers en Python, un domaine où la gestion des exceptions est particulièrement importante.
Commentaires
Les commentaires sont alimentés par GitHub Discussions
Connectez-vous avec GitHub pour participer à la discussion