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.