2.25. Gestion des erreurs#
La plupart des problèmes d’exécution en Python se manifestent sous forme d”exceptions – une manière nommée et structurée de signaler qu’un problème est survenu. ValueError, TypeError, KeyError, OSError, MemoryError en sont autant d’exemples ; chacune est une classe, et en lever une interrompt l’appel en cours pour chercher un gestionnaire dans le code environnant.
2.25.1. try / except#
Encadrez un bloc de code dans try pour intercepter toute exception qu’il lève :
try:
n = int(input_text)
except ValueError:
n = 0
Si la conversion int(...) échoue, le contrôle saute au bloc except au lieu de propager l’erreur plus loin. Si input_text était une chaîne d’entier valide, le bloc except est ignoré.
Un seul try peut comporter plusieurs blocs except, chacun interceptant un type d’erreur différent :
try:
value = data[key]
except KeyError:
value = None
except TypeError:
value = -1
Python établit la correspondance dans l’ordre ; le premier dont la classe d’exception convient traite le problème. Intercepter Exception (la classe de base de presque tout) traite toute erreur ; réservez cela à la couche la plus externe d’un programme, où l’alternative serait un plantage.
Avertissement
Un except: nu (sans classe après le mot-clé) intercepte aussi KeyboardInterrupt – l’exception que l’IDE envoie lorsque vous appuyez sur son bouton stop pour interrompre un script en cours. Une boucle enveloppée dans un except: pass nu avalera l’interruption et continuera de tourner, ne laissant aucun moyen d’arrêter le script hormis une coupure d’alimentation.
Préférez except Exception: à un except: nu lorsque vous avez véritablement besoin d’intercepter largement. KeyboardInterrupt hérite de BaseException, et non de Exception, donc except Exception: laisse le bouton stop fonctionnel.
2.25.1.1. Inspecter l’exception#
Pour lire le message attaché à une exception, nommez-la avec as :
try:
f = open("data.txt")
except OSError as e:
print("could not open file:", e)
La variable liée par as n’est valide qu’à l’intérieur du bloc except.
2.25.2. else et finally#
Un bloc try dispose de deux ajouts facultatifs.
else ne s’exécute que lorsque le try s’est terminé sans rien lever :
try:
value = compute()
except ValueError:
print("bad input")
else:
print("got", value)
Placer « ce qu’il faut faire en cas de succès » dans else garde le bloc try étroit – seule la ligne susceptible d’échouer appartient au try.
finally s’exécute à la fin quoi qu’il arrive – que le try ait réussi, qu’il ait levé une exception interceptée, ou qu’il en ait levé une sur le point de se propager :
try:
do_work()
finally:
cleanup()
finally s’exécute toujours. else ne s’exécute que sur le chemin sans exception.#
Pour la plupart des motifs acquisition/libération, préférez un gestionnaire de contexte à un couple try / finally – la ressource elle-même gère son propre nettoyage.
2.25.3. Exceptions intégrées courantes#
Une courte liste des exceptions que vous rencontrerez souvent :
ValueError– type correct, valeur incorrecte (bytes([300])– 300 est du bon type, mais hors de la plage d’octets valide 0..255).TypeError– type totalement incorrect (len(42)).IndexError– indice au-delà de la fin d’une séquence.AttributeError– accès à un attribut inexistant ("abc".foo).OSError– une défaillance du système de fichiers ou d’E/S.MemoryError– plus de mémoire sur le tas. Sur un environnement d’exécution à mémoire contrainte, cela peut survenir lors d’un fonctionnement normal – pas seulement dans des cas pathologiques.