La gestion des exceptions en Python

Exceptions Python

Gérer une exception

La gestion des exceptions permet à un programme de faire face aux erreurs d’exécution et continuer son exécution normale.
Considérons le programme suivant :

a=input("Entrer un entier: ")
nombre=int(a)
inverse=1/nombre
print("l'inverse de %d est %f " % (nombre,inverse))

Qu’est-ce qui se passe si l’utilisateur entre une valeur nulle ou non-numérique ? Le programme s’arrêtera et lèvera une erreur comme indiqué ci-dessous.

Entrer un entier: 0 <b><----- valeur nulle</b>
Traceback (most recent call last):
File "", line 3, in
<u>ZeroDivisionError: division by zero</u>
Entrer un entier: <b>sss</b> <----- valeur non-numérique
Traceback (most recent call last):
File "", line 2, in
<b>ValueError: invalid literal for int() with base 10: 'sss'</b>

Dans le premier cas le programme a levé l’exception ZeroDivisionError et dans le deuxième cas, il a levé l’exception ValueError.

Les messages d’erreurs donnent des informations sur la ligne qui a causé l’erreur en remontant aux appels de fonction qui conduisent à cette instruction. Les numéros de ligne des appels de fonction sont affichés dans le message d’erreur pour permettre une correction rapide du code.

Une erreur qui se produit lors de l’exécution est appelée aussi « exception ». Comment pouvez-vous faire face à une exception afin que le programme puisse attraper l’erreur et invite l’utilisateur à entrer un nombre correct?

Cela peut être fait en utilisant l’instruction « try ». Cette instruction suit la syntaxe suivante:

try:
   <corps>

except <TypeException>:

   <traitement>

Ici, contient le code qui peut soulever une exception. Lorsqu’une exception se produit, le reste du code dans est ignoré. Si l’exception correspond à un type d’exception, le gestionnaire correspondant est exécuté. est le code qui traite l’exception.

Maintenant, on va essayer d’éviter les exceptions citées ci-dessus on réécrivant notre code comme suit.

try:
   a=input("Entrer un entier: ")
   nombre=int(a)
   inverse=1/nombre
   print("l'inverse de %d est %f " % (nombre,inverse))

except ZeroDivisionError:
   print("Erreur: Division par zéro!")

except ValueError:
   print("Erreur: Valeur non-numérique")

Remarquez que ce code va être exécuté une seule fois même si l’utilisateur peut saisir une valeur incorrecte. Dans ce cas le programme n’aboutira pas son objectif qui est calculer l’inverse d’un nombre saisi par l’utilisateur. Donc, il faut que notre programme demande à l’utilisateur de re-saisir un nouveau nombre en cas d’erreur.

while True:
   try:
      a=input("Entrer un entier: ")
      nombre=int(a)
      inverse=1/nombre
      print("l'inverse de %d est %f " % (nombre,inverse))
      break# sortie de la boucle
   except ZeroDivisionError:
      print("Erreur: Division par zéro!")
   except ValueError:
      print("Erreur: Valeur non-numérique")

Le programme utilise une boucle while pour demander à plusieurs reprises à l’utilisateur d’entrer un nombre. Si le nombre est correct, le programme sortira de la boucle (instruction break).

Si une exception est déclenchée, la clause « except » qui correspond à l’exception sera exécutée pour traiter l’exception et la boucle continuera.

Le bloc« try/except » ci-dessus fonctionne comme suit:

  • Les instructions situées entre try et except sont exécutées premièrement.
  • Si aucune exception ne s’estpas produite, la clause d’exception sera sautée. Dans ce cas, l’instruction break est exécutée pour sortir de la boucle while.
  • Si une exception s’est produite lors de l’exécution de la clause try, le reste de la clause est ignorée. Dans ce cas, si la valeur saisie est non-numérique, la fonction int() déclenchera une exception et l’instruction break est ignorée.
  • Quand une exception estlevée, si le type d’exception correspond au nom d’une exception situé après unmot-cléexcept, la clause d’exception correspondante sera exécutée, puis l’exécution du programme se poursuit directement à ligne qui suit le bloctry/except courant.
  • Si une exception s’est produite et elle ne correspond pas au nom d’une exception attaché à une clause exceptet il n’existe pas de clause « exceptpar défaut » (clause except sans nom d’exception), l’exécution s’arrêtera avec un message d’erreuraffiché. Par contre si le code contient une clause « except par défaut », le corps dela clause d’exception est exécuté, puis l’exécution se poursuit après le bloctry/except courant.

Une instruction try peut avoir plus d’une seule clause d’exception pour gérer différentes exceptions. Elle peut aussi avoir une option else et/ou finally dans une syntaxe comme suit:

try:
   <corps>

except<TypeException1>:
   <traitement1>
    ...

except<TypeExceptionN>:
   < traitement N>

except:
   <traitement except par défaut>

else:
   <traitement else>

finally:
   <traitement finally>

Les multiples clauses except sont semblables aux clauses elif. Lorsqu’une exception se produit, elle est vérifiée pour pouvoir correspondre à une exception attachée à une clause except.

Si une clause est trouvée, le traitement correspondant est exécuté et le reste des clauses except sont ignorées.

Si l’exception ne correspond à aucun des types d’exceptions cités après la clause try, le bloc d’instruction « traitement except par défaut »sera exécuté.

Une instruction try peut avoir une clause facultative else, qui est exécutée si aucune exception n’est levée.
Une instruction try peut avoir une clause facultative finally qui est destiné à définir des actions qui doivent être effectuées dans toutes les circonstances (production d’exception ou pas).

Lever une exception

Vous avez appris à écrire du code pour gérer les exceptions dans la section précédente. D’où une exception vient-t-elle? Comment une exception est créée?

Les informations relatives à une exception sont encapsulées dans un objet.Une exception est levée à partir d’une fonction : lorsqu’une fonction détecte une erreur, il crée un objet d’une classe d’exception appropriée et lève l’exception à l’appelant de la fonction, en utilisant la syntaxe suivante:

raiseClasseException (“Quelque chose ne va pas !”)

Voici comment cela fonctionne. Supposons que le programme a détecté qu’un argument passé en paramètre à une fonction viole le contrat de la fonction; par exemple, l’argument doit être positif ou nul, mais un argument négatif a étéy passé.

Le programme peut créer une instance de la classe RuntimeError et déclencher l’exception, comme suit:

ex = RuntimeError("argument incorrecte")
raise ex

Ou, si vous préférez, vous pouvez combiner les deux instructions précédentes en une comme suit:

raiseRuntimeError("argument incorrecte")

Vous pouvez maintenant modifier la méthode de ChangerRayon() dans la classe Cercle (voir chapitre sur les objets et les classes)afin de soulever une exception RuntimeError si le rayon est négatif. Voici le nouveau code de la méthode ChangerRayon().

def ChangerRayon(self, r):

   if r < 0:
      raiseRuntimeError("Rayon négatif")

   else:
      self.__radius = r

Le programme de test ci-dessous crée des objets de type Cercle à l’aide de la nouvelle classe Cercle.

from Cercle import Cercle

try:
   c1 = Cercle(5)
   print("l’aire de c1est ", c1.ObtenirAire())
   c2 = Cercle(-5)
   print("l’aire de c2est ", c2.ObtenirAire())
   c3 = Cercle(0)
   print("l’aire de c3est ", c3.ObtenirAire())

exceptRuntimeError:
   print("Rayon invalide")

Lorsque vous essayez de créer un objet Cercle avec un rayon négatif, une erreur d’exécution est élevée. L’exception est gérée dans la clause except RuntimeError. Dans ce cas, on afficher le message « Rayon invalide ».

Si vous voulez afficher le message d’erreur d’origine (càd, l’un défini dans la classe Cercle), vous devez écrire la clause except RuntimeError comme suit.

except RuntimeError as ex:
   print(ex)

 

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here