Version en ligne

Tutoriel : Les exceptions

Table des matières

Les exceptions
Les mots-clés try, except, else et finally
Liste des exceptions built-in
Vos propres exceptions

Les exceptions

Les mots-clés try, except, else et finally

Si vous codez en Python, vous avez sûrement déjà été confronté(e) à des erreurs diverses, provenant de l'utilisateur, d'une bibliothèque, etc.
Par exemple, vous souhaitez que l'utilisateur entre un nombre et que votre programme affiche le triple de ce nombre.
Si vous utilisez input() , mais que l'utilisateur entre une chaîne de caractères (sans l'entourer de guillemets), le programme plante lamentablement.
Si vous utilisez raw_input() , vous n'avez pas de problème lors de la saisie, mais vous vous retrouvez avec une chaîne. Or, vous avez besoin d'un nombre.
Si vous utilisez int() pour transformer la chaîne obtenue en nombre, le programme plantera aussi dans le cas où l'utilisateur n'a pas entré un nombre.
Alors, comment remédier à un tel problème ?

Ce tutoriel va vous expliquer comment gérer les erreurs en Python.
Une première partie vous enseignera comment utiliser les mots-clé try , except , finally et else , tandis que la seconde vous présentera une liste des exceptions et des exemples les expliquant. Enfin, la troisième vous expliquera comment créer vos propres exceptions.

Les mots-clés try, except, else et finally

Liste des exceptions built-in

Quatre mots-clés vont servir à gérer les erreurs.

try permet « d'essayer » un bout de code. Si une erreur est rencontrée, on cesse d'interpréter le code et on passe aux except , qui permettent d'agir en fonction de l'erreur qui s'est produite. C'est pourquoi try doit toujours être suivi d'au moins un except ou d'un finally .
Nous allons, pour comprendre leur fonctionnement, analyser le code suivant.

try:
    fichier = open("foo.txt", "r")
    print int("abc")
except IOError:
    print "Erreur lors de l'ouverture du fichier !"
except ValueError:
    print "Erreur lors de la conversion !"

Les deux premières lignes, dans le try: , sont tout d'abord interprétées. La première tente d'ouvrir un fichier appelé foo.txt. Si ce fichier existe dans le répertoire du script, remplacez "foo.txt" par autre chose, de sorte que le fichier que le script tente d'ouvrir n'existe pas.
La seconde essaie d'afficher à l'écran la chaîne "abc" convertie en nombre.
La troisième ligne, qui contient le mot-clé except , est exécutée en cas d'IOError . IOError est l'exception lancée lorsqu'il s'avère impossible d'ouvrir un fichier (entre autres). Dans ce cas, on affiche une erreur. La cinquième ligne agit comme la troisième, en cas de ValueError , qui est lancé quand on passe un argument avec le bon type (ici, "abc" est bien une chaîne), mais que la valeur n'est pas correcte ("abc" ne saurait être transformée en nombre, vous en conviendrez).
Lorsque nous lançons ce code, comme foo.txt n'existe pas, l'ouverture du fichier provoque une IOError . Si nous le créons (touch foo.txt sous UNIX), alors la ligne print int("abc") sera interprétée et lancera une ValueError . Si, enfin, nous remplaçons "abc" par "22" (ou toute autre chaîne qui peut être convertie en nombre), alors aucune exception ne sera lancée et seul le bloc try: aura été exécuté.

On peut également mettre un tuple d'exceptions, pour les cas où le même code doit être interprété pour des erreurs différentes :

except (IOError, ValueError):

Il est possible de créer une instance de l'exception, afin d'avoir plus d'informations sur une erreur :

try:
    fichier = open('foo.txt')
except IOError, e:
    print e
[Errno 2] No such file or directory: 'foo.txt'

Le mot-clé else permet d'interpréter du code lorsqu'aucune exception n'a été lancée dans le try: . Ainsi, on pourrait rajouter une lecture du fichier dans le code précédent :

try:
    fichier = open("foo.txt", "r")
    print int("22")
except IOError:
    print "Erreur lors de l'ouverture du fichier !"
except ValueError:
    print "Erreur lors de la conversion !"
else:
    print fichier.read()

Ainsi, si le fichier s'est ouvert sans problème, et le reste du code (ici symbolisé par le int("22") ) aussi, le fichier sera lu.

Enfin, le mot-clé finally permet d'exécuter du code après l'ensemble try: except: , quoi qu'il arrive (qu'une exception ait été lancée ou non, qu'un return ou un break soit rencontré, le bloc finally: sera interprété).


Liste des exceptions built-in

Liste des exceptions built-in

Les mots-clés try, except, else et finally Vos propres exceptions

Cette partie propose une liste des exceptions built-in en Python, accompagnées pour la plupart d'un exemple.
Certaines exceptions en contiennent d'autres : par exemple, Exception regroupe toutes les exceptions, exceptés KeyboardInterrupt , SystemExit , et bien sûr, BaseException , qui regroupe l'ensemble des exceptions. La hiérarchie est la suivante :

Les autres Warnings portent des noms tout à fait explicites, si bien qu'il est inutile de radoter autour.


Les mots-clés try, except, else et finally Vos propres exceptions

Vos propres exceptions

Liste des exceptions built-in

Pour des raisons pratiques, vous serez peut-être amené(e) un jour à faire vos propres exceptions.
Nous allons comprendre comment le faire en analysant ce code :

class MonException(Exception):
    def __init__(self,raison):
        self.raison = raison
    
    def __str__(self):
        return self.raison

def multiplier_par_5(n):
    if n > 20:
        raise MonException("Le nombre est trop grand !")
    else:
        return n * 5

Nous créons ici une classe nommée MonException, avec deux méthodes. __init__ prend comme argument raison. La fonction __str__ est celle qui est appelée lorsqu'on tente d'afficher l'instance de l'exception que j'ai jusqu'ici appelée e. Ici, elle renvoie raison.
Il y a ensuite une fonction multiplier_par_5() , qui multiplie l'argument n par 5 à condition que celui-ci ne soit pas plus grand que 20. Dans le cas contraire, on utilise le mot-clé raise pour lancer l'exception. C'est aussi simple que cela.
Finalement, cette fonction utilisée pourrait donner ceci :

try:
    print multiplier_par_5(2)
    print multiplier_par_5(21)
except MonException, e:
    print e
10
Le nombre est trop grand !

Maintenant, vous pouvez ajouter des attributs (comme par exemple la taille du nombre envoyé, pour que __str__ puisse afficher « Le nombre 21 est trop grand ! » par exemple. De plus, l'utilisateur pourrait s'en servir pour afficher l'erreur soi-même, par exemple en faisant print e.n, "est plus grand que 20 ; erreur !" .

Vous voilà désormais capable de gérer tout type d'erreur en Python.
En effet, lorsque vous faites int() , avec une chaîne qui n'est pas transformable en un nombre, vous obtenez une ValueError . Vous n'avez qu'à faire une boucle, et ne pas la terminer tant que vous obtiendrez une ValueError . Voici mon code :

while 1:
    try:
        a = int(raw_input("Entrez un nombre : "))
        break
    except ValueError:
        print "Ce n'est pas un nombre !"
print a*3

Merci à #python pour les conseils qui m'ont été donnés, et à Klouguinette pour sa zCorrection incomparable. :')


Liste des exceptions built-in