Exceptions
Les exceptions se produisent quand une situation exceptionnelle arrive dans votre programme. Par exemple, que se passe-t-il quand vous voulez lire un fichier et que ce fichier n'existe pas ? Ou quand vous le détruisez par erreur pendant l'exécution du programme ? De telles situations sont gérées en utilisant des exceptions.
De la même manière, que se passe-t-il si votre programme contient des instructions incorrectes ? Cela est géré par Python qui lève la main et vous dit qu'il y a une erreur.
Erreurs
Considérez un simple appel à la fonction print
. Que se passe-t-il si nous faisons une faute de frappe et écrivons Print
à la place de print
? Notez la lettre majuscule. Dans ce cas, Python lève une erreur de syntaxe.
Observez qu'une NameError
est levée et que l'emplacement où l'erreur a été détectée est affiché. C'est le travail du gestionnaire d'erreur de cette erreur.
Exceptions
Nous allons essayer de lire la saisie de l'utilisateur. Entrez la première ligne ci-dessous et appuyez sur la touche Entrée
. Lorsque votre ordinateur vous invite à saisir, faites à la place [ctrl-d]
sur Mac ou [ctrl-z]
sous Windows pour voir ce qui se passe. (Si vous utilisez Windows et qu'aucune des deux options ne fonctionne, essayez [ctrl-c]
dans l'invite de commande pour générer une erreur KeyboardInterrupt
à la place).
Python lève une erreur appelée EOFError
qui signifie en gros qu’il a trouvé un symbole de fin de fichier (End Of File) (représenté par [ctrl-d]
) alors qu’il ne s’attendait pas à le voir.
Gérer les exceptions
We can handle exceptions using the try..except
statement. We basically put our usual statements within the try-block and put all our error handlers in the except-block.
Exemple (enregistrez sous exceptions_handle.py
):
Résultat:
Comment ça marche
Nous mettons toutes les instructions qui peuvent lever des exceptions/erreurs à l'intérieur du bloc try
et gérons les erreurs/exceptions prévues dans la clause (ou bloc) except
. La clause except
peut gérer une seule erreur ou exception spécifiée, ou une liste d'erreurs ou d'exceptions entre parenthèses. Si le nom des erreurs ou exceptions à gérer n'est pas specifié, le bloc gérera toutes les erreurs et exceptions.
Notez qu'il faut avoir au moins une clause except
associée à chaque clause try
. Sinon, quel serait l'intérêt d'avoir un bloc try ?
Si une erreur ou exception n'est pas gérée, alors le gestionnaire par default de Python est appelé, il arrête l'exécution du programme et affiche un message d'erreur. Nous avons déjà testé cela plus haut.
Vous pouvez aussi avoir une clause else
associée à un bloc try..except
. La clause else
est exécutée lorsqu'on ne rencontre pas d'exception.
Dans l'exemple suivant, nous verrons comment récupérer l'objet d'exception afin d'obtenir des informations supplémentaires.
Lever des exceptions
Vous pouvez lever des exceptions avec l'instruction raise
en fournissant le nom de l'erreur/exception et l'objet exception qui sera lancé.
L'erreur ou exception que vous levez doit être une classe qui doit être dérivée directement ou indirectement de la classe Exception
.
Exemple (enregistrez sous exceptions_raise.py
):
Résultat:
Comment ça marche
Nous créons ici notre propre type d'exception. Ce nouveau type d'exception est appelé ShortInputException
. Il possède deux champs: length
qui est la longueur saisie, et atleast
qui est la longueur minimum attendue par le programme.
Dans la clause except
, nous indiquons la classe de l'erreur qui sera stockée en tant que ex
(as ex
), le nom de variable qui va contenir l'objet d'erreur/exception correspondant. Cela est comparable aux paramètres et arguments dans un appel de fonction. A l'intérieur de cet clause except
, nous utilisons les champs length
et atleast
de l'objet exception pour afficher le message approprié à l'utilisateur.
Try ... Finally
Supposons, vous lisez un fichier dans votre programme. Comment être certain que l'objet fichier est fermé proprement, indépendament du fait qu'une exception soit levée ou non dans le code qui le manipule ? Cela se fait à l'aide d'un bloc finally
.
Enregistrez ce programme sous exceptions_finally.py
:
Résultat:
Comment ça marche
Nous faisons notre lecture de fichier habituelle, mais nous avons introduit de manière arbitraire une pause de 2 secondes après l’impression de chaque ligne à l’aide de la fonction time.sleep
afin que le programme s’exécute lentement (Python est très rapide par nature). Pendant que le programme est en cours d'exécution, appuyez sur ctrl + c
pour l'interrompre.
Notez que l'exception KeyboardInterrupt
est levée et que le programme se ferme. Cependant, avant sa fermeture, la clause finally
est exécutée et l'objet fichier est fermé.
Notez également qu'une variable affectée d'une valeur de 0 ou None
ou d'une variable qui contient séquence ou une collection vide est considérée comme False
par Python. C'est pourquoi nous pouvons utiliser if: f
dans le code ci-dessus.
Notez également que nous utilisons sys.stdout.flush()
après print
pour nous garantir que le message soit immédiatement affiché à l'écran.
L'instruction with
with
Acquérir une ressource dans le bloctry
et la relâcher dans le bloc finally
arrive très fréquement. Par conséquent, il y a aussi une instruction with
qui permet de faire cela de manière plus lisible :
Enregistrez sous exceptions_using_with.py
:
Comment ça marche
Le résultat devrait être le même que dans l'exemple précédent. La différence est que nous utilisons la fonction open
avec l'instruction with
et nous laissons la fermeture du fichier se faire automatiquement avec with open
.
Ce qui se passe en arrière-plan est qu'un protocole est utilisé par l'instruction with
. Il recherche l'objet retourné par l'instruction open
, appelons-le thefile
dans ce cas.
Il appelle toujours la fonction thefile.__enter__
avant de commencer le bloc de code en dessous et appelle toujours thefile.__exit__
après avoir terminé le bloc de code.
Donc la méthode __exit__
prendra en charge le code que nous aurions écrit dans un bloc finally
. C'est ce qui nous aide à éviter d'utiliser des instructions try..finally
de manière répétitive.
Une discussion plus approfondie sur ce sujet est au-delà de l'objectif de ce livre, consultez PEP 343 pour une explication détaillée.
Récapitulatif
Nous avons vu comment utiliser les instructions try..except
et try..finally
. Nous avons vu comment créer nos propres types d'exceptions et comment lever des exceptions.
Ensuite, nous allons explorer la bibliothèque standard de Python.
Dernière mise à jour