Tutoriel Python: gestion des exceptions

Table des matières

Introduction

Exceptions : Définition générale

Liste des exceptions standards

Gérer des exceptions simples

Gérer des exceptions spécifiques

Levée des exceptions

Try avec le else

Try et finally

Exceptions définies par l’utilisateur

Conclusion

Introduction :

Bienvenue dans un nouveau tutoriel Python , aujourd’hui nous allons nous intéresser aux exceptions et comment les gérer selon les cas. Nous allons commencer par définir ce qu’est une exception pour ensuite voir les différents types d’exceptions et leur manipulation . Ce cours sera riche en exemples  afin de vous permettre de bien maîtriser cette notion .

Pour suivre ce tutoriel, vous devez avoir les notions de base en programmation comme les structures , les opérateurs , les classes… . Cependant, il suffit de bien suivre les sections et s’appliquer dans les exemples et le tour sera joué !

Commençons notre tutoriel alors !

Exceptions : Définition générale

Généralement, une exception est un cas spécial, une chose extraordinaire. En programmation, une exception est un évènement qui interrompt le déroulement normal des instructions d’un programme.

Python a de nombreuses exceptions intégrées qui sont soulevées lorsque votre programme rencontre une erreur.

Liste des exceptions standards :

Voici une table qui résume quelques exceptions de la liste standard des exceptions, elle vous sera très utile pour comprendre la signification des exceptions que vous rencontrerez lors de l’exécution de votre programme :

Nom d’exception

Description de l’exception

System.exit()

Relevé par la fonction sys.exit()

Arithmetic error

Classe de base des erreurs de calcul numérique

Exception

Classe de base des erreurs de toutes les exceptions

StopIteration

Soulevé lorsque la méthode next() d’un itérateur ne pointe vers aucun objet.

StandardError

Classe de base pour toutes les exceptions intégrées sauf StopIteration et SystemExit .

OverflowError

Relevé lorsqu’un calcul dépasse la limite maximale pour un type numérique.

FloatingPointError

Relevé lorsqu’un calcul à virgule flottante échoue.

ZeroDivisionError

Relevé lorsque la division ou modulo par zéro a lieu pour tous les types numériques.

AssertionError

Soulevé en cas d’échec de la déclaration Assert.

AttributeError

Soulevé en cas de défaillance de la référence d’attribut ou de l’affectation.

EOFError

Soulevé lorsqu’il n’y a pas d’entrée de la fonction raw_input() ou input() et que la fin du fichier est atteinte .

KeyboardInterrupt

Soulevé lorsque l’utilisateur interrompt l’exécution du programme, généralement en appuyant sur Ctrl+c .

ImportError

Soulevée lorsqu’un relevé d’importation échoue.

UnboundLocalError

Élevé lorsque vous essayez d’accéder à une variable locale dans une fonction ou une méthode, mais aucune valeur n’y a été attribuée.

NameError

Soulevé lorsqu’un identifiant n’est pas trouvé dans l’espace de noms local ou global.

IndexError

Élevé lorsqu’un index n’est pas trouvé dans une séquence.

IOError

Soulevé lorsqu’une opération d’entrée / sortie échoue, comme l’instruction d’impression ou la fonction open() lorsque vous essayez d’ouvrir un fichier qui n’existe pas.

Gérer des exceptions simples :

En Python, les exceptions sont traitées grâce à l’instruction try . L’opération critique qui peut soulever une exception est placée à l’intérieur de la clause try. Le code qui traite les exceptions est écrit dans la clause d’exception .

Nous pouvons donc choisir quelles opérations effectuer une fois que nous avons attrapé l’exception. Voici un exemple simple.

Le module sys nous permet de savoir le type de l’exception relevée .

Exemple :

Dans ce premier exemple , on veut calculer l’inverse des éléments d’une liste . La liste est composée de trois éléments : une chaine de caractère, 0 et 3 . On sait que l’inverse de 0 et d’une chaîne de caractère est impossible. Comment gérer ces deux cas ?

Syntaxe :

import sys
Liste = ['bonjour', 0, 3]
for e in Liste:
try:
print("l’entrée est :", e)
r = 1/int(e)
break
except:
print ("Oups!", sys.exc_info()[0], "est relevé.")
print ("Next entry.")
print()
print ("l’inverse de ", e, "est", r)

On commence par importer le module sys pour identifier le type de l’exception . Ensuite on déclare notre liste nommée Liste .

La boucle for permet de calculer l’inverse de tous les éléments de la liste . Comme nous l’avons mentionné avant, la partie sensible qui contient le code est placée dans le block try.

Si aucune exception ne se produit, le bloc excepté est ignoré et le flux normal continue (pour la dernière valeur). Mais si une exception se produit, elle est captée par le bloc except (première et deuxième valeurs).

Ici, nous imprimons le nom de l’exception en utilisant la fonction exc_info() dans le module sys. Nous pouvons voir qu’une cause ValueError et 0 cause ZeroDivisionError.

Résultat de l’exécution :

On peut écrire le code d’une autre façon vu que toutes les exceptions héritent de la classe Exception.

import sys
Liste = ['bonjour', 0, 2]
for e in Liste:
try:
print ("L’entrée est", e)
r = 1/int(e)
break
except Exception as e:
print ("Oups!", e.__class__, "est relevée.")
print ("Entrée suivante.")
print ()
print ("L’inverse de", e, "est", r)

Résultat de l’exécution :

L’exécution donne  le  même résultat que le précédent.

Exemple :

Dans cet exemple, on veut écrire un programme qui retourne l’entier d’un nombre . Par exemple fonction (4.999) doit retourner 4 . Sans oublier qu’on veut gérer l’exception valueError pour les variables qui ne sont pas des nombres .

Syntaxe :

def fonction(variable):
try:
return int(variable)
except ValueError :
print ("la variable n'est pas un nombre\n")
# On fait appel à la fonction .
Fonction ("xyz")
Fonction (2.3)

Résultat de l’exécution :

Gérer des exceptions spécifiques :

Dans l’exemple ci-dessus, nous avons vu le cas des exceptions simples sans traiter chaque cas spécifiquement. Normalement, ce n’est pas une bonne pratique de programmation. Chaque exception doit être spécifique.

La syntaxe générale pour écrire des exceptions est la suivante :

try:
# faire instruction
pass
except exception1 :
# gérer l’exception exception1
pass
except (exception2 , exception 3 ):
# gérer des exceptions multiples
# exception1 et exception2
pass
except:
# gérer d’autres exceptions
pass

Voici un exemple de traitement des exceptions dans des blocs séparés :

Exemple :

Cas 1 : a=0

Dans ce premier exemple, on va tester la division sur 0 !

Syntaxe :

a=0
try:
print (1/int(a))
pass
except ValueError:
print (" a n'est pas un nombre")
pass
except (TypeError, ZeroDivisionError):
# gérer des exceptions multiples
# TypeError et ZeroDivisionError
print (" division impossible")
pass
except:
# gérer d’autres exceptions
pass

Résultat de l’exécution :

Comme vous pouvez le constater le programme ignore la première exception car 0 est un nombre. Par contre, on ne pas diviser par 0 donc l’exception ZeroDivisionError  est relevée et le message de l’exception est affiché.

Syntaxe :

a = 'hi'
try:
print (1/int(a))
pass
except ValueError:
print (" a n'est pas un nombre")
pass
except (TypeError, ZeroDivisionError):
# gérer des exceptions multiples
# TypeError et ZeroDivisionError
print ("division impossible")
pass
except:
# gérer d’autres exceptions
pass

Résultat de l’exécution :

Dans ce deuxième cas, a=’hi’ est une chaine de caractère donc l’exception 

Levée des exceptions :

Dans la programmation Python, les exceptions sont levées lorsque des erreurs se produisent à l’exécution. Nous pouvons également soulever manuellement les exceptions en utilisant le mot-clé raise .
Nous pouvons éventuellement passer des valeurs à l’exception pour clarifier pourquoi cette exception a été soulevée.

Exemple :

Dans cet exemple on veut relever une exception si un nombre n’est pas négatif.

Syntaxe :

try:
... a = int (input("Entrer un nombre négatif "))
... if a >= 0:
... raise ValueError ("Ce nombre n'est pas négatif!")
... except ValueError as ve:
... print (ve)

Comme vous pouvez le voir le mot raise est utilisé à l’intérieur de la clause try et après le if . Si un nombre est supérieur ou égale à 0 on relève alors l’exception.

Résultat de l’exécution :

Exemple :

Dans cet exemple on veut lever une exception si la longeur d’une chaîne de caractère dépasse 6 puis afficher le message (« la chaîne est trop longue») .

Syntaxe :

chaine = 'Bonjour'
longeur_chaine = len (chaine)
try:
if longeur_chaine>6:
raise MemoryError ('la chaine est trop longue !')
except MemoryError as me :
print (me)

Résultat de l’exécution :

 Exemple :

Dans ce dernier exemple, on veut tester si un nombre est pair . Ci ce n’est pas le cas on relève une exception ValueError avec le message (« Le nombre n’est pas pair il ne peut être utilisé ») .

Syntaxe :

nombre = input (" entrez le nombre ! ")
try:
if int (nombre) %2!=0 :
raise ValueError (" Le nombre n’est pas pair il ne peut être utilisé !")
except ValueError as me :
print (me)

Résultat de l’exécution :

Try avec le else :

Dans certaines situations, vous pouvez lancer un certain bloc de code si le bloc de code à l’intérieur de try s’exécute sans aucune erreur. Pour ces cas, vous pouvez utiliser le mot-clé optionnel else avec l’instruction try.

Syntaxe générale :

try:
instructions
except:
message d'exception
else:
instructions

Exemple :

Dans cet exemple on veut écrire un programme qui retourne l’inverse d’un nombre s’il est pair sinon il relève  une exception.

Syntaxe :

# program to print the reciprocal of even numbers
try:
nombre = int (input ("Enter un nombre: "))
assert nombre % 2 == 0
except:
print ("Nombre non accepté !")
else:
inverse = 1/nombre
print (inverse) 

 Résultat de l’exécution :

Exemple :

Dans cet exemple on veut rendre les mots d’une liste en majuscule mais à condition que sa longeur ne dépasse pas 4 .

Syntaxe :

Cas 1 : longueur adéquate

Liste= [ "tutoriel" , "python" ]
new_liste= []
try:
assert len (Liste)except:
print (" La liste est trop longue ")
else:
for e in Liste :
new_liste.append (e.upper())
print (new_liste)

Résultat de l’exécution :

Cas 2 : liste trop longue

Liste= ["Bonjour", "ca va", "tutoriel" , "python" ]
new_liste=[]
try:
assert len(Liste)except:
print (" La liste est trop longue ")
else:
for e in Liste :
new_liste.append(e.upper())
print (new_liste)

 Résultat de l’exécution :

Try et finally :

Le try de Python peut avoir une clause optionnelle nommée finally. L’avantage de cette clause est qu’elle est exécutée quoi qu’il arrive dans le programme.

Syntaxe générale :

try :
Instructions
finally :
Instructions

Exemple :

Dans l’exemple suivant, on veut afficher x alors qu’on ne l’a pas. Donc le programme doit afficher « quelque chose ne vas pas» . Ainsi que le message « le ‘try except ‘ block est terminé »  doit absolument apparaître .

Syntaxe :

try:
print(x)
except:
print (" Quelque chose ne vas pas")
finally:
print ("le 'try except' block est terminé ")

Résultat de l’exécution :

Dans la section suivante nous allons voir comment écrire des exceptions définies par l’utilisateur :

Exceptions définies par l’utilisateur :

Dans cette dernière section, nous allons voir comment définir des exceptions personnalisées.

Python a de nombreuses exceptions intégrées qui forcent votre programme à produire une erreur lorsque quelque chose dans le programme tourne mal.

Cependant, parfois, vous pouvez avoir besoin de créer vos propres exceptions personnalisées qui servent votre but.

En Python, définir des exceptions personnalisées est réalisé en créant une nouvelle classe. Cette dernière, doit être dérivée de la classe d’exception intégrée. La plupart des exceptions intégrées sont également dérivées de cette classe.

Exemple :

Dans cet exemple, on veut écrire un programme qui définit ses propres exceptions et qui permet à un utilisateur de deviner un nombre jusqu’à ce qu’il tombe sur le bon nombre dont la valeur est connue d’avance.

On va définir deux exceptions la première est relevée si le nombre deviné par l’utilisateur est trop petit nous l’appellerons ErreurValeurTropPetite, la deuxième est relevée si le nombre deviné est trop grand que celui qu’on cherche, nous l’appellerons ErreurValeurTropGrande .

Notez que les deux exceptions héritent de la classe de base Erreur.

Syntaxe :

# exceptions définies par l’utilisateur
class Erreur(Exception):
"""Classe de Base de toutes les exceptions"""
pass
class ErreurValeurTropPetite (Erreur):
""" Relevée quand la valeur est trop petite"""
pass
class ErreurValeurTropGrande (Erreur):
""" Relevée quand la valeur est trop grande """
pass
# l’utilisateur doit trouver le nombre
nombre = 10
# l’utilisateur doit deviner un nombre jusqu’a ce qu’il tombe sur le bon
while True:
try:
j_num = int (input ("Entrer un nombre: "))
if j_num raise ErreurValeurTropPetite
elif j_num > nombre:
raise ErreurValeurTropGrande
break
except ErreurValeurTropPetite:
print ("Cette valeur est trop petite essayez encore une autre fois !")
print()
except ErreurValeurTropGrande:
print ("Cette valeur est trop grande essayez encore une autre fois")
print()
print ( " Félicitations ! Vous l’avez trouvé " )

Résultat de l’exécution :

Exemple : Classe salarié

Syntaxe :

class SalaireHorsPlageErreur (Exception):
"""Exception raised for errors in the input salary. """
def __init__(self, salaire, message="Salaire n’appartient pas a la plage (5000, 15000)"):
self.salaire = salaire
self.message = message
super().__init__(self.message)
salaire= int (input ("Entrer valeur du salaire: "))
if not 5000 raise SalaireHorsPlageErreur (salaire)

Résultat de l’exécution :

Conclusion :

Nous sommes arrivés à la fin de ce tutoriel, nous supposons que vous avez appris beaucoup de notions importantes ! Maintenant vous savez ce que c’est une exception et comment la gérer vous pouvez écrire des programmes efficaces et comprendre les erreurs d’exécutions si il y’en a. Nous vous conseillons de refaire les exemples pas mal de fois afin de bien les assimiler.

Vous êtes au milieu de la route ! Pleins de surprises vous attendent ! Continuez sur cette voie. À un prochain tutoriel chers lecteurs !

Article publié le 21 Octobre 2020par Mouna HAMIM