Gestion des exceptions en Python

PythonBeginner
Pratiquer maintenant

Introduction

En informatique et en programmation, la gestion des exceptions est le processus consistant à répondre à la survenue d'exceptions, c'est-à-dire des conditions anormales ou exceptionnelles nécessitant un traitement particulier. Python dispose de nombreuses exceptions intégrées qui sont déclenchées lorsqu'un programme rencontre une erreur. De plus, de nombreuses bibliothèques externes incluent leurs propres exceptions personnalisées que vous devrez savoir gérer.

Dans ce laboratoire, vous apprendrez les fondamentaux de la gestion des exceptions en Python. Vous commencerez par les blocs try et except de base, passerez à la gestion de plusieurs exceptions, comprendrez l'utilité du bloc finally et, pour finir, créerez et gérerez vos propres exceptions personnalisées.

Gestion de base des exceptions

Dans cette étape, vous apprendrez les bases de la gestion des exceptions en Python en utilisant les blocs try et except.

C'est un fait mathématique : on ne peut pas diviser par zéro. Si vous tentez de le faire en Python, l'interpréteur déclenchera une exception intégrée appelée ZeroDivisionError. Voyons cela en pratique.

Remarque : Si vous n'êtes pas familier avec l'utilisation de WebIDE (similaire à VS Code), veuillez d'abord consulter ce laboratoire.

Tout d'abord, ouvrez le fichier basic_handler.py depuis l'explorateur de fichiers sur la gauche et ajoutez le code suivant. Cela définit une fonction de division simple.

def divide(dividend , divisor):
    print(dividend / divisor)

divide(dividend=10, divisor=5)

Maintenant, exécutez le script depuis le terminal :

python3 basic_handler.py

Vous verrez le résultat correct :

2.0

Ensuite, voyons ce qui se passe lorsque nous essayons de diviser par zéro. Modifiez la dernière ligne de basic_handler.py pour appeler divide avec un diviseur de 0 :

def divide(dividend , divisor):
    print(dividend / divisor)

divide(dividend=10, divisor=0)

Exécutez à nouveau le script :

python3 basic_handler.py

Cette fois, le programme plante et affiche une trace d'erreur (traceback), indiquant une ZeroDivisionError :

Traceback (most recent call last):
  File "/home/labex/project/basic_handler.py", line 4, in <module>
    divide(dividend=10, divisor=0)
  File "/home/labex/project/basic_handler.py", line 2, in divide
    print(dividend / divisor)
ZeroDivisionError: division by zero

Pour éviter que le programme ne plante et afficher plutôt un message convivial, nous pouvons "gérer" l'exception en utilisant try et except. Le code susceptible de provoquer une erreur est placé à l'intérieur du bloc try, et le code à exécuter si cette erreur survient est placé dans le bloc except.

Mettez à jour le fichier basic_handler.py avec le code suivant pour gérer la ZeroDivisionError proprement :

## try-except: gérer les exceptions avec élégance
def divide(dividend , divisor):
    try:  ## Essayer d'exécuter ce code
        print(dividend / divisor)
    except ZeroDivisionError:  ## Capturer un type d'exception spécifique
        print('You can not divide by 0')

divide(dividend=10, divisor=0)

Maintenant, exécutez le script une fois de plus :

python3 basic_handler.py

Au lieu de planter, le programme affiche désormais le message utile que vous avez défini, et l'exécution se termine normalement :

You can not divide by 0

Gestion de plusieurs exceptions dans un seul bloc

Dans cette étape, vous découvrirez comment gérer plusieurs types d'exceptions différents au sein d'un seul bloc except. Cela est utile pour simplifier votre code de gestion des erreurs lorsque plusieurs types d'erreurs peuvent survenir.

Vous pouvez capturer un tuple d'exceptions, tel que (ZeroDivisionError, TypeError), pour les traiter avec la même logique.

Ouvrez le fichier multiple_handler.py et ajoutez le code suivant. Cette fonction est conçue pour potentiellement déclencher soit une TypeError (en essayant de concaténer une chaîne et un entier), soit une ZeroDivisionError.

## Gérer plusieurs exceptions dans un seul bloc except
def divide(dividend , divisor):
    try:
        if (dividend == 10):
          var = 'str' + 1  ## Cela déclenchera une TypeError
        else:
          print(dividend / divisor)
    except (ZeroDivisionError, TypeError) as error:  ## Capturer plusieurs types d'exceptions
        print(error)  ## Afficher le message d'erreur

divide(dividend=20, divisor=5)

Tout d'abord, exécutons le code dans un scénario où aucune exception ne survient. Exécutez le script :

python3 multiple_handler.py

Le résultat sera le résultat de la division :

4.0

Maintenant, déclenchons la TypeError. Modifiez la dernière ligne de multiple_handler.py pour utiliser 10 comme dividende :

## ... (reste du code) ...
divide(dividend=10, divisor=5)

Exécutez à nouveau le script :

python3 multiple_handler.py

Le bloc except capture la TypeError et affiche le message d'erreur associé :

can only concatenate str (not "int") to str

Enfin, déclenchons la ZeroDivisionError. Modifiez à nouveau la dernière ligne, cette fois en essayant de diviser par zéro. Notez que la condition TypeError (dividend == 10) n'est pas remplie.

## ... (reste du code) ...
divide(dividend=20, divisor=0)

Exécutez le script :

python3 multiple_handler.py

Le même bloc except capture maintenant la ZeroDivisionError et affiche son message :

division by zero

Pour que la vérification réussisse, assurez-vous que l'appel final dans votre script est divide(dividend=10, divisor=5) afin de déclencher la TypeError.

Le bloc finally dans la gestion des exceptions

Dans cette étape, vous comprendrez le but et l'utilisation du bloc finally. Le code contenu dans une clause finally est toujours exécuté, qu'une exception ait été déclenchée ou gérée ou non. Cela le rend idéal pour les opérations de nettoyage, comme la fermeture d'un fichier ou d'une connexion réseau.

Voyons comment cela fonctionne. Ouvrez le fichier finally_handler.py et ajoutez le code suivant :

## bloc finally: s'exécute toujours, indépendamment des exceptions
def divide(dividend , divisor):
    try:
        print(dividend / divisor)
    except ZeroDivisionError:
        print('You can not divide by 0')
    finally:  ## S'exécute toujours, même si une exception survient
        print('Execution finished')

divide(dividend=10, divisor=5)

Exécutez le script depuis votre terminal :

python3 finally_handler.py

Dans ce cas, aucune exception ne survient. Le bloc try se termine avec succès, puis le bloc finally est exécuté.

2.0
Execution finished

Maintenant, introduisons une erreur. Modifiez la dernière ligne de finally_handler.py pour diviser par zéro :

## ... (reste du code) ...
divide(dividend=10, divisor=0)

Exécutez à nouveau le script :

python3 finally_handler.py

Cette fois, une ZeroDivisionError est déclenchée et capturée par le bloc except. Même si une exception s'est produite, le bloc finally est toujours exécuté après la fin du bloc except.

You can not divide by 0
Execution finished

Comme vous pouvez le constater, le message "Execution finished" est affiché dans les deux scénarios, démontrant que le bloc finally est un endroit fiable pour le code qui doit toujours s'exécuter.

Exceptions personnalisées

Dans cette étape, vous apprendrez à créer vos propres exceptions personnalisées. Il s'agit d'une fonctionnalité puissante pour rendre vos applications plus lisibles et maintenables, car vous pouvez créer des types d'erreurs spécifiques qui décrivent des problèmes propres au domaine de votre programme.

Les exceptions personnalisées sont définies en créant une nouvelle classe qui hérite de la classe de base Exception de Python. Vous pouvez ensuite déclencher cette exception en utilisant le mot-clé raise.

Ouvrez le fichier custom_exception.py et ajoutez le code suivant pour définir et déclencher une exception personnalisée simple :

## Exception personnalisée : créée en héritant de la classe Exception
class MyCustomException(Exception):
    pass

raise MyCustomException  ## Déclencher l'exception personnalisée

Si vous exécutez ce script, il s'arrêtera immédiatement et affichera une trace d'erreur pour votre nouvelle exception :

python3 custom_exception.py
Traceback (most recent call last):
  File "/home/labex/project/custom_exception.py", line 5, in <module>
    raise MyCustomException  ## Déclencher l'exception personnalisée
__main__.MyCustomException

Vous pouvez également fournir un message descriptif lorsque vous déclenchez une exception personnalisée. Modifiez custom_exception.py pour passer une chaîne de caractères à votre exception :

class MyCustomException(Exception):
    pass

raise MyCustomException('A custom message for my custom exception')

L'exécution affichera votre message dans la trace d'erreur :

Traceback (most recent call last):
  File "/home/labex/project/custom_exception.py", line 4, in <module>
    raise MyCustomException('A custom message for my custom exception')
__main__.MyCustomException: A custom message for my custom exception

La gestion d'une exception personnalisée se fait de la même manière que pour une exception intégrée : en utilisant un bloc try...except. Mettez à jour custom_exception.py vers sa forme finale, qui déclenche et gère l'exception personnalisée :

class MyCustomException(Exception):
    pass

try:
    raise MyCustomException('A custom message for my custom exception')
except MyCustomException:
    print('My custom exception was raised')

Maintenant, exécutez le script pour la dernière fois :

python3 custom_exception.py

Le programme ne plante plus. Au lieu de cela, il exécute le code dans le bloc except et affiche votre message de confirmation :

My custom exception was raised

Résumé

Dans ce laboratoire, vous avez appris les techniques essentielles pour gérer les exceptions en Python. Vous avez commencé par les blocs try et except de base pour capturer des erreurs spécifiques et éviter les plantages du programme. Vous avez ensuite appris à gérer efficacement plusieurs types d'exceptions dans un seul bloc except. Vous avez également exploré le bloc finally, crucial pour le code de nettoyage qui doit toujours s'exécuter. Enfin, vous avez acquis la capacité de créer, déclencher et gérer vos propres exceptions personnalisées, vous permettant de construire une logique de gestion des erreurs plus robuste et descriptive dans vos applications.