La gestion des erreurs sous Python
Qui n'a jamais eu d'erreur en exécutant un code Python ? Une division par 0, une variable mal orthographiée ou une liste pas assez longue, on a tous déjà du comprendre pourquoi nous avons une erreur. Mais il convient de bien différencier deux types d'erreurs qui peuvent survenir en Python.

Qui n'a jamais eu d'erreur en exécutant un code Python ? Une division par 0, une variable mal orthographiée ou une liste pas assez longue, on a tous déjà du comprendre pourquoi nous avons une erreur. Mais il convient de bien différencier deux types d'erreurs qui peuvent survenir en Python.
- Les erreurs de syntaxe, qui surviennent lorsque l'on n'écrit pas correctement une variable ou un mot-clé Python.
- Les exceptions, qui sont des erreurs survenant lors de l'exécution du programme.
La principale différence, c'est que les erreurs de syntaxe sont détectées avant l'exécution du programme, alors que les exceptions surviennent pendant l'exécution du programme.
Heureusement pour nous, avec Python, il est possible de gérer les exceptions, c'est-à-dire pouvoir les détecter et les isoler pour ne pas stopper l'exécution du programme.
❓ Pourquoi a-t-on besoin de gérer les exceptions ?
Imaginons que le programme soit exécuté sur un serveur. Si nous avons, à un moment, une erreur que nous n'avons pas géré, cela peut faire crasher le programme !
Il vaut donc mieux éviter que cela se produise.
Gérer les erreurs
Commençons par voir comment gérer très facilement une erreur. Prenons le code suivant qui va générer une erreur puisque l'on va additionner un nombre (type int) avec une chaîne de caractères (type str).
num = 10
num += "3"
L'erreur est de type TypeError : cela signifie qu'il y a une incompatibilité entre les types. Avec le mot-clé try, nous allons essayer d'éviter l'arrêt du programme en cas d'erreur.
À lire aussi : découvrez notre formation MLOps
num = 10
# Le mot-clé try délimite le moment à partir duquel une erreur qui intervient sera gérée
try:
num += "3"
except:
print("Une erreur est survenue.")
Ici, le mot-clé except va simplement exécuter des instructions en cas d'erreur. En particulier, un message sera affiché pour avertir l'utilisateur qu'une erreur est survenue.
Maintenant, si l'on souhaite avoir plus d'informations sur la nature de l'erreur, notamment à l'aide d'une description plus explicite. Dans ce cas, il est possible de récupérer les informations l'erreur dans une variable.
num = 10
try:
num += "3"
except Exception as e:
print("L'erreur suivante est survenue :", e)
En plus de gérer l'erreur survenue, nous pouvons en afficher les détails.
Gestion en fonction du type d'erreur
Naturellement, dans un code Python, il n'y a pas qu'une seule source d'erreur qui peut survenie : plusieurs types d'erreurs sont possibles dans un même bloc d'instruction. Là encore, il est possible de gérer plusieurs cas en fonction de la nature de l'erreur.
Nous allons effectuer trois erreurs de nature différente :
- Une erreur de type
TypeError, similaire à celle réalisée plus haut. - Une autre erreur de type
NameError, où une variable sera mal orthographiée. - Une dernière erreur inconnue de type
Exception.
Exécutons le code suivant.
num = 10
try:
num += "3"
print("Pas d'erreur.")
except TypeError as e:
print("Erreur : incompatibilité de types.")
finally:
print("Ce print sera quand même exécuté.")
Avec le mot clé except suivi d'un type d'erreur particulier, nous sommes capable de gérer un type particulier d'erreur. En conséquence, nous pourrions effectuer un traitement spécifique lorsqu'une erreur particulière apparaît.
⚠️ Il est déconseillé, en pratique, d'utiliser le mot-clé `except` tout seul, sans le type d'erreur. Selon la norme PEP8, il faut au maximum toujours spécifier un type d'erreur.
Enfin, le mot-clé finally sera exécuté quel que soit l'issue du bloc try .. except. Qu'il y ait une erreur ou pas, cela permet de définir des instructions à ne pas manquer même si une erreur s'est produite.
Prenons maintenant le code suivant où la variable num est mal orthographiée.
num = 10
try:
nuum += "3"
print("Pas d'erreur.")
except TypeError as e:
print("Erreur : incompatibilité de types.")
except NameError as e:
print("Erreur de nommage :", e)
finally:
print("Ce print sera quand même exécuté.")
Maintenant, en fonction de la nature de l'erreur, nous pouvons rediriger l'exécution vers un bloc spécifique. Ici, il s'agit d'un NameError et l'affichage sera donc différent du cas où l'erreur était de type TypeError.
Enfin, pour une erreur générique, nous pouvons toujours utiliser le type Exception : il s'agit de l'équivalent du else pour les exceptions.
num = 10
try:
num /= 0
print("Erreur : incompatibilité de types.")
except TypeError as e:
print("Incompatibilité de types")
except NameError as e:
print("Erreur de nommage :", e)
except Exception as e:
print("Erreur inconnue :", e)
finally:
print("Ce print sera quand même exécuté.")
Remarquons, pour terminer, que même s'il n'y a pas eu d'erreur, le bloc finally sera quand même exécuté.
num = 10
try:
num += 3
print("Pas d'erreur.")
except TypeError as e:
print("Incompatibilité de types")
except NameError as e:
print("Erreur de nommage :", e)
except Exception as e:
print("Erreur inconnue :", e)
finally:
print("Ce print sera quand même exécuté.")
Pour aller plus loin
Une dernière chose qui peut être intéressante lorsqu'une erreur survient, c'est de remonter la pile d'appel pour savoir précisement où et comment l'erreur est survenue. Pour utiliser la pile d'appel (ou d'exécution), on utilise le traceback sous Python.
À lire aussi : découvrez notre formation MLOps
import traceback
num = 10
try:
num /= 0
except Exception:
print("Une erreur est survenue :")
traceback.print_exc() # Affiche la pile d'appel de l'exception
Il en faut pas non plus faire de la gestion d'exceptions partout. Par exemple, lorsque c'est prévisible, un if ... else peut être suffisant. La gestion des exceptions doit être utilisée dans un cadre critique où une erreur pourrait être fatale pour le programme.


