Python - Exceptions Définies par l'Utilisateur

Bonjour à tous, futurs sorciers Python ! Aujourd'hui, nous allons embarquer dans un voyage passionnant dans le monde des exceptions définies par l'utilisateur en Python. Ne vous inquiétez pas si vous êtes nouveau en programmation ; je vais vous guider à travers cette aventure étape par étape, comme je l'ai fait pour d'innombrables étudiants au fil des années. Alors, prenez vos baguettes virtuelles (claviers), et plongeons-y !

Python - User-defined Exception

Exceptions Définies par l'Utilisateur en Python

Avant de commencer à créer nos propres exceptions, récapitulons rapidement ce qu'ont sont les exceptions. Imaginez que vous cuisinez un délicieux repas, mais que vous réalisez soudain que vous n'avez plus d'un ingrédient crucial. C'est quelque chose comme une exception en programmation – c'est une situation inattendue qui perturbe le flux normal de votre code.

Python est livré avec de nombreuses exceptions intégrées, comme ValueError, TypeError et ZeroDivisionError. Mais parfois, nous devons créer nos propres exceptions spéciales pour gérer des situations uniques dans nos programmes. C'est là que les exceptions définies par l'utilisateur deviennent pratiques !

Comment Créer une Exception Définie par l'Utilisateur

Créer votre propre exception est aussi simple que de faire un gâteau (bien, une recette de gâteau facile). Tous ce que vous avez besoin de faire est de créer une nouvelle classe qui hérite de la classe intégrée Exception ou de l'un de ses sous-classes. Regardons un exemple simple :

class MonErreurSpéciale(Exception):
pass

C'est tout ! Vous avez juste créé votre première exception définie par l'utilisateur. La déclaration pass est utilisée parce que nous n'avons pas besoin d'ajouter de fonctionnalité supplémentaire à notre classe d'exception.

Mais que faire si nous voulons que notre exception soit un peu plus informative ? Créons-en une autre :

class ValueTooLargeError(Exception):
def __init__(self, message, value):
self.message = message
self.value = value

Dans cet exemple, nous avons ajouté une méthode __init__ à notre classe d'exception. Cela nous permet de transmettre des informations supplémentaires lorsque nous levons l'exception.

Lever des Exceptions Définies par l'Utilisateur

Maintenant que nous avons nos exceptions personnalisées, voyons comment nous pouvons les utiliser dans notre code. Lever une exception est comme déclencher une alarme lorsque quelque chose va mal. Voici comment vous pouvez le faire :

def check_value(value):
max_value = 100
if value > max_value:
raise ValueTooLargeError("La valeur est trop grande !", value)
print(f"La valeur {value} est acceptable.")

# Essayons cela
try:
check_value(150)
except ValueTooLargeError as error:
print(f"Oups ! {error.message} La valeur était {error.value}")

Dans cet exemple, nous vérifions si une valeur est trop grande. Si c'est le cas, nous levons notre ValueTooLargeError avec un message personnalisé et la valeur réelle.

Gérer les Exceptions Définies par l'Utilisateur

Gérer les exceptions définies par l'utilisateur est tout comme gérer les exceptions intégrées. Nous utilisons le bloc try-except fiable. Étendons notre exemple précédent :

def process_value(value):
try:
check_value(value)
except ValueTooLargeError as error:
print(f"Erreur : {error.message} La valeur {error.value} n'est pas autorisée.")
# Ici, vous pourriez ajouter du code pour gérer l'erreur, comme demander une nouvelle valeur
else:
print("Valeur traitée avec succès !")
finally:
print("Vérification de la valeur terminée.")

# Essayons avec différentes valeurs
process_value(50)
process_value(200)

Dans ce code, nous utilisons un bloc try-except pour gérer notre ValueTooLargeError. Nous avons également ajouté une clause else qui s'exécute si aucune exception n'est levée, et une clause finally qui s'exécute toujours, indépendamment du fait qu'une exception se soit produite ou non.

Exemple Complet

Maintenant, mettons tout ensemble dans un exemple plus complexe. Imaginez que nous créons un simple système bancaire :

class InsufficientFundsError(Exception):
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
self.message = f"Fonds insuffisants. Solde : ${balance}, Retrait tenté : ${amount}"

class NegativeAmountError(Exception):
def __init__(self, amount):
self.amount = amount
self.message = f"Impossible de traiter un montant négatif : ${amount}"

class BankAccount:
def __init__(self, balance=0):
self.balance = balance

def deposit(self, amount):
if amount < 0:
raise NegativeAmountError(amount)
self.balance += amount
print(f"Dépôt de ${amount}. Nouveau solde : ${self.balance}")

def withdraw(self, amount):
if amount < 0:
raise NegativeAmountError(amount)
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
print(f"Retrait de ${amount}. Nouveau solde : ${self.balance}")

# Utilisons notre classe BankAccount
account = BankAccount(100)

try:
account.deposit(50)
account.withdraw(30)
account.withdraw(200)  # Cela devrait lever un InsufficientFundsError
except NegativeAmountError as error:
print(f"Erreur : {error.message}")
except InsufficientFundsError as error:
print(f"Erreur : {error.message}")
else:
print("Toutes les transactions ont été complétées avec succès.")
finally:
print(f"Solde final : ${account.balance}")

Dans cet exemple, nous avons créé une classe BankAccount avec des méthodes deposit et withdraw. Nous avons également défini deux exceptions personnalisées : InsufficientFundsError et NegativeAmountError.

Lorsque nous essayons de retirer plus d'argent que nous n'avons dans le compte, cela lève une InsufficientFundsError. Si nous essayons de déposer ou de retirer un montant négatif, cela lève une NegativeAmountError.

C'est un excellent exemple de la manière dont les exceptions définies par l'utilisateur peuvent rendre notre code plus lisible et nous aider à gérer des cas d'erreur spécifiques de manière claire et organisée.

Conclusion

Félicitations ! Vous venez de monter de niveau dans vos compétences Python en apprenant sur les exceptions définies par l'utilisateur. Ces exceptions personnalisées sont comme votre armée personnelle de captureurs d'erreurs, prêt à entrer en action lorsque quelque chose d'inattendu se produit dans votre code.

N'oubliez pas, la clé pour maîtriser les exceptions définies par l'utilisateur est la pratique. Essayez de créer vos propres exceptions pour différents scénarios, et bientôt vous gérezz les erreurs comme un pro !

Voici un tableau de référence rapide des méthodes que nous avons couvertes :

Méthode Description
class CustomError(Exception): Crée une nouvelle classe d'exception
raise CustomError() Lève une exception personnalisée
try: Démarre un bloc try
except CustomError as error: Capture une exception personnalisée spécifique
else: S'exécute si aucune exception n'est levée
finally: S'exécute toujours, indépendamment des exceptions

Bon codage, et que vos exceptions soient toujours capturées !

Credits: Image by storyset