Maîtriser la gestion d'exceptions en Python : Guide complet
Python offre deux fonctionnalités importantes pour gérer les erreurs inattendues dans vos programmes et ajouter des capacités de débogage :
Gestion des exceptions : couverte dans ce tutoriel. Voici une liste des exceptions standard disponibles en Python : Exceptions standard.
Assertions : couvertes dans le tutoriel "Assertions en Python".
Liste des exceptions standard
| N° | Exception et description |
|---|---|
| 1 | Exception Classe de base pour toutes les exceptions |
| 2 | StopIteration Levée quand next() d'un itérateur ne pointe vers aucun objet. |
| 3 | SystemExit Levée par sys.exit(). |
| 4 | StandardError Classe de base pour toutes les exceptions intégrées sauf StopIteration et SystemExit. |
| 5 | ArithmeticError Classe de base pour toutes les erreurs de calcul numérique. |
| 6 | OverflowError Levée quand un calcul dépasse la limite maximale d'un type numérique. |
| 7 | FloatingPointError Levée quand un calcul en virgule flottante échoue. |
| 8 | ZeroDivisionError Levée lors d'une division ou modulo par zéro pour tous les types numériques. |
| 9 | AssertionError Levée en cas d'échec de l'instruction assert. |
| 10 | AttributeError Levée en cas d'échec de référence ou d'assignation d'attribut. |
| 11 | EOFError Levée quand il n'y a plus d'entrée depuis raw_input() ou input() et que la fin de fichier est atteinte. |
| 12 | ImportError Levée quand une instruction import échoue. |
| 13 | KeyboardInterrupt Levée quand l'utilisateur interrompt l'exécution (généralement Ctrl+C). |
| 14 | LookupError Classe de base pour toutes les erreurs de recherche. |
| 15 | IndexError Levée quand un index n'est pas trouvé dans une séquence. |
| 16 | KeyError Levée quand une clé spécifiée n'est pas trouvée dans un dictionnaire. |
| 17 | NameError Levée quand un identificateur n'est pas trouvé dans l'espace de noms local ou global. |
| 18 | UnboundLocalError Levée en tentant d'accéder à une variable locale non assignée. |
| 19 | EnvironmentError Classe de base pour les exceptions survenant hors de l'environnement Python. |
| 20 | IOError Levée quand une opération d'entrée/sortie échoue (ex: open() sur fichier inexistant). |
| 21 | OSError Levée pour les erreurs liées au système d'exploitation. |
| 22 | SyntaxError Levée quand il y a une erreur de syntaxe Python. |
| 23 | IndentationError Levée quand l'indentation n'est pas correcte. |
| 24 | SystemError Levée quand l'interpréteur trouve un problème interne sans quitter. |
| 25 | SystemExit Levée quand l'interpréteur quitte via sys.exit(). Si non gérée, cause la sortie. |
| 26 | TypeError Levée quand une opération est invalide pour le type de données spécifié. |
| 27 | ValueError Levée quand une fonction intégrée a le bon type d'arguments mais des valeurs invalides. |
| 28 | RuntimeError Levée quand une erreur générée ne rentre dans aucune catégorie. |
| 29 | NotImplementedError Levée quand une méthode abstraite n'est pas implémentée dans une classe dérivée. |
Les assertions en Python
Une assertion est un test de santé mentale que vous pouvez activer ou désactiver une fois les tests terminés.
Le plus simple est de comparer une assertion à une instruction raise-if (ou plus précisément raise-if-not). Une expression est testée, et si le résultat est faux, une exception est levée.
Les assertions sont effectuées par l'instruction assert, mot-clé introduit en Python 1.5.
Les programmeurs placent souvent des assertions au début d'une fonction pour vérifier les entrées valides, et après un appel de fonction pour vérifier les sorties valides.
L'instruction assert
Lorsqu'elle rencontre une instruction assert, Python évalue l'expression qui l'accompagne. Si l'expression est fausse, Python lève une exception AssertionError.
La syntaxe de assert est :
assert Expression[, Arguments]
Si l'assertion échoue, Python utilise ArgumentExpression comme argument pour AssertionError. Les exceptions AssertionError peuvent être capturées et gérées comme toute autre exception avec try-except, mais si non gérées, elles terminent le programme et produisent une trace.
Exemple
Voici une fonction qui convertit une température de Kelvin en Fahrenheit. Comme zéro Kelvin est le plus froid possible, la fonction s'arrête si elle voit une température négative :
#!/usr/bin/python
def KelvinToFahrenheit(Temperature):
assert (Temperature >= 0), "Colder than absolute zero!"
return ((Temperature - 273) * 1.8) + 32
print(KelvinToFahrenheit(273))
print(int(KelvinToFahrenheit(505.78)))
print(KelvinToFahrenheit(-5))
L'exécution produit :
32.0
451
Traceback (most recent call last):
File "test.py", line 9, in
print(KelvinToFahrenheit(-5))
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0), "Colder than absolute zero!"
AssertionError: Colder than absolute zero!
Qu'est-ce qu'une exception ?
Une exception est un événement qui se produit pendant l'exécution d'un programme et perturbe le flux normal des instructions. En général, quand un script Python rencontre une situation qu'il ne peut pas gérer, il lève une exception. Une exception est un objet Python représentant une erreur.
Lorsqu'un script lève une exception, il doit soit la gérer immédiatement, sinon il se termine et quitte.
Gestion d'une exception
Si vous avez du code suspect qui peut lever une exception, vous pouvez protéger votre programme en plaçant ce code dans un bloc try:. Après le bloc try:, incluez une instruction except:, suivie d'un bloc de code qui gère le problème le plus élégamment possible.
Syntaxe
Voici la syntaxe simple des blocs try....except...else :
try:
# Vos opérations ici
......................
except ExceptionI:
# Si ExceptionI, exécuter ce bloc
except ExceptionII:
# Si ExceptionII, exécuter ce bloc
......................
else:
# Si aucune exception, exécuter ce bloc
Points importants :
Un seul
trypeut avoir plusieursexcept. Utile quand le bloctrycontient des instructions qui peuvent lever différents types d'exceptions.Vous pouvez fournir une clause
exceptgénérique qui gère toute exception.Après les clauses
except, vous pouvez inclure une clauseelse. Le code dans le blocelses'exécute si le bloctry:ne lève pas d'exception.Le bloc
elseest un bon endroit pour le code qui n'a pas besoin de la protection du bloctry:.
Exemple : Succès
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print("Error: can't find file or read data")
else:
print("Written content in the file successfully")
fh.close()
Résultat :
Written content in the file successfully
Exemple : Échec
#!/usr/bin/python
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError:
print("Error: can't find file or read data")
else:
print("Written content in the file successfully")
Résultat :
Error: can't find file or read data
Clause except sans exception spécifiée
Vous pouvez utiliser except sans exception définie :
try:
# Vos opérations
......................
except:
# Si toute exception, exécuter ce bloc
......................
else:
# Si aucune exception, exécuter ce bloc
Ce type d'instruction try-except capture toutes les exceptions. Ce n'est pas considéré comme une bonne pratique car cela ne permet pas d'identifier la cause racine du problème.
Clause except avec plusieurs exceptions
Vous pouvez utiliser le même except pour gérer plusieurs exceptions :
try:
# Vos opérations
......................
except (Exception1[, Exception2[,...ExceptionN]]):
# Si une exception de la liste, exécuter ce bloc
......................
else:
# Si aucune exception, exécuter ce bloc
Clause try-finally
Vous pouvez utiliser un bloc finally: avec un bloc try:. Le bloc finally contient du code qui doit s'exécuter, que le bloc try ait levé une exception ou non.
try:
# Vos opérations
......................
# Peut être ignoré suite à une exception
finally:
# Sera toujours exécuté
......................
Vous ne pouvez pas utiliser la clause else avec une clause finally.
Exemple
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
finally:
print("Error: can't find file or read data")
Si vous n'avez pas la permission d'ouvrir le fichier en écriture :
Error: can't find file or read data
Même exemple écrit plus proprement :
#!/usr/bin/python
try:
fh = open("testfile", "w")
try:
fh.write("This is my test file for exception handling!!")
finally:
print("Going to close the file")
fh.close()
except IOError:
print("Error: can't find file or read data")
Lorsqu'une exception est levée dans le bloc try, l'exécution passe immédiatement au bloc finally. Après l'exécution de toutes les instructions du bloc finally, l'exception est relévée et gérée dans les instructions except si présentes dans la couche supérieure du try-except.
Argument d'une exception
Une exception peut avoir un argument, une valeur donnant des informations supplémentaires sur le problème. Le contenu varie selon l'exception. Vous capturez l'argument en fournissant une variable dans la clause except :
try:
# Vos opérations
......................
except ExceptionType, Argument:
# Vous pouvez afficher la valeur de l'argument ici...
Pour une seule exception, une variable peut suivre le nom de l'exception. Pour plusieurs exceptions, une variable peut suivre le tuple d'exceptions.
Cette variable reçoit la valeur de l'exception, contenant généralement la cause. Elle peut recevoir une valeur unique ou un tuple (chaîne d'erreur, numéro d'erreur, localisation).
Exemple
#!/usr/bin/python
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print("The argument does not contain numbers\n", Argument)
temp_convert("xyz")
Résultat :
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
Lever une exception
Vous pouvez lever des exceptions de plusieurs façons avec l'instruction raise. La syntaxe générale est :
raise [Exception [, args [, traceback]]]
Exception est le type (ex: NameError), argument est une valeur pour l'argument (optionnel, None par défaut), traceback est optionnel (rarement utilisé).
Exemple
def functionName(level):
if level < 1:
raise "Invalid level!", level
# Le code ci-dessous ne s'exécute pas si on lève l'exception
Note : Pour capturer une exception, une clause except doit référencer la même exception levée (objet classe ou chaîne simple). Pour capturer l'exception ci-dessus :
try:
# Logique métier
except "Invalid level!":
# Gestion de l'exception
else:
# Reste du code
Exceptions définies par l'utilisateur
Python permet de créer vos propres exceptions en dérivant des classes des exceptions intégrées standard.
Exemple lié à RuntimeError : une classe est créée en sous-classant RuntimeError. Utile pour afficher des informations plus spécifiques lors de la capture.
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
Une fois la classe définie, vous pouvez lever l'exception ainsi :
try:
raise Networkerror("Bad hostname")
except Networkerror, e:
print(e.args)
Python
- Maîtriser les types de données Python : Guide pratique
- Maîtriser les opérateurs Python : Guide complet
- Maîtriser l'instruction pass en Python : Guide pratique
- Maîtriser les arguments de fonctions Python : Positionnels, nommés et paramètres par défaut
- Maîtriser les dictionnaires Python : création, manipulation et techniques avancées
- Maîtriser les erreurs et exceptions intégrées de Python
- Maîtriser la gestion d'exceptions Python : try, except, else et finally expliqués
- Maîtriser les exceptions personnalisées Python : guide pratique
- Maîtriser les itérateurs Python : fonctionnement et création des vôtres