cours
Gestion des exceptions et des erreurs en Python
Les erreurs et les exceptions peuvent entraîner un comportement inattendu, voire empêcher l'exécution d'un programme. Python propose diverses fonctions et mécanismes pour gérer ces problèmes et améliorer la robustesse du code. Dans ce tutoriel, nous apprendrons à connaître les différents types d'erreurs et les fonctions intégrées à l'aide d'exemples.
Une erreur est un problème dans un programme qui l'empêche d'accomplir sa tâche. En comparaison, une exception est une condition qui interrompt le déroulement normal du programme. Les erreurs et les exceptions sont un type d'erreur d'exécution, ce qui signifie qu'elles se produisent pendant l'exécution d'un programme.
En d'autres termes, l'erreur est un problème critique qu'une application normale ne doit pas détecter, tandis que l'exception est une condition qu'un programme doit détecter.
Nous allons en apprendre davantage sur les erreurs et les exceptions en examinant divers exemples. Pour les exécuter facilement, vous pouvez créer gratuitement un classeur DataLab dans lequel Python est préinstallé et qui contient tous les échantillons de code.
Erreurs dans Python
Voici un exemple d'erreur de syntaxe où un retour en dehors de la fonction ne signifie rien. Nous ne devons pas traiter les erreurs dans un programme. Au lieu de cela, nous devons créer une fonction qui renvoie la chaîne de caractères.
return "DataCamp"
Input In [1]
return "DataCamp"
^
SyntaxError: 'return' outside function
Nous avons créé la fonction, mais avec une indentation incorrecte. Nous ne devrions pas gérer les erreurs d'indentation au moment de l'exécution. Soit nous le faisons manuellement, soit nous utilisons des outils de formatage de code.
def fun():
return "DataCamp"
Input In [2]
return "DataCamp"
^
IndentationError: expected an indented block
Les exceptions en Python
Nous avons rencontré une ZeroDivisionError (Exception). Nous pouvons le gérer au moment de l'exécution en utilisant les blocs `try` et `except`.
test = 1/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 test = 1/0
ZeroDivisionError: division by zero
Les exceptions de type NameError sont assez courantes lorsqu'une variable n'est pas trouvée. Nous pouvons également gérer l'exception en remplaçant la variable ou en imprimant l'avertissement.
y = test
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [5], in <cell line: 1>()
----> 1 y = test
NameError
Exceptions intégrées à Python
Voici la liste des exceptions par défaut de Python avec leur description :
- AssertionError : levée lorsque l'affirmation échoue.
- Erreur EOFError : levée lorsque la fonction input() rencontre la condition de fin de fichier.
- AttributeError : levée lorsque l'attribution ou la référence d'un attribut échoue.
- TabError : levée lorsque les indentations sont constituées de tabulations ou d'espaces incohérents.
- ImportError : levée lorsque l'importation du module échoue.
- IndexError : se produit lorsque l'index d'une séquence est en dehors de la plage.
- KeyboardInterrupt : levée lorsque l'utilisateur saisit des touches d'interruption (Ctrl + C ou Suppr).
- RuntimeError : se produit lorsqu'une erreur n'entre dans aucune catégorie.
- NameError : levée lorsqu'une variable n'est pas trouvée dans la portée locale ou globale.
- MemoryError : levée lorsque les programmes manquent de mémoire.
- Erreur de valeur : se produit lorsque l'opération ou la fonction reçoit un argument du bon type mais de la mauvaise valeur.
- ZeroDivisionError : levée lorsque vous divisez une valeur ou une variable par zéro.
- SyntaxError : levée par l'analyseur syntaxique lorsque la syntaxe Python est incorrecte.
- IndentationError : se produit lorsque l'indentation est incorrecte.
- SystemError : levée lorsque l'interprète détecte une erreur interne.
Vous trouverez une liste complète des erreurs et exceptions en Python en lisant la documentation.
Apprenez à connaître les exceptions Python en suivant notre cours Programmation orientée objet en Python. Il vous apprendra à créer des classes et à tirer parti de l'héritage et du polymorphisme pour réutiliser et optimiser le code.
Traitement des exceptions avec try, except, else et finally
Après avoir découvert les erreurs et les exceptions, nous apprendrons à les gérer en utilisant les blocs try, except, else et finally.
Qu'entendons-nous donc par les traiter ? Dans des circonstances normales, ces erreurs interrompent l'exécution du code et affichent le message d'erreur. Pour créer des systèmes stables, nous devons anticiper ces erreurs et proposer des solutions alternatives ou des messages d'avertissement.
Dans cette section, nous verrons ce que fait chaque bloc et comment nous pouvons les utiliser pour écrire un code robuste.
Déclaration d'essai et d'exception
La façon la plus simple de gérer les exceptions en Python est d'utiliser les blocs `try` et `except`.
- Exécutez le code sous l'instruction `try`.
- Lorsqu'une exception est levée, exécutez le code sous l'instruction `except`.
Au lieu de s'arrêter à une erreur ou à une exception, notre code se tournera vers d'autres solutions.
Exemple simple
Dans le premier exemple, nous allons essayer d'imprimer la variable indéfinie `x`. Dans des circonstances normales, il devrait lever l'erreur et arrêter l'exécution, mais avec les blocs `try` et `except`, nous pouvons changer le comportement du flux.
- Le programme exécutera le code sous l'instruction `try`.
- Comme nous savons que `x` n'est pas défini, l'instruction except sera exécutée et l'avertissement sera affiché.
try:
print(x)
except:
print("An exception has occurred!")
An exception has occurred!
Exemple de déclaration d'exceptions multiples
Dans le second exemple, nous utiliserons plusieurs instructions `except` pour gérer plusieurs types d'exceptions.
- Si une exception ZeroDivisionError est levée, le programme affiche "Vous ne pouvez pas diviser une valeur par zéro".
- Pour les autres exceptions, le message "Quelque chose d'autre n'a pas fonctionné" s'affiche.
Il nous permet d'écrire un code flexible qui peut gérer plusieurs exceptions à la fois sans se casser la figure.
try:
print(1/0)
except ZeroDivisionError:
print("You cannot divide a value with zero")
except:
print("Something else went wrong")
You cannot divide a value with zero
Chargement du fichier exemple
Prenons maintenant un exemple plus concret.
Dans le code ci-dessous, nous lisons le fichier CSV, et lorsqu'il soulève l'exception FileNotFoundError, le code affiche l'erreur et un message supplémentaire concernant le fichier `data.csv`.
Oui, nous pouvons imprimer des messages d'erreur par défaut sans interrompre l'exécution.
try:
with open('data.csv') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
print("Explanation: We cannot load the 'data.csv' file")
[Errno 2] No such file or directory: 'data.csv'
Explanation: We cannot load the 'data.csv' file
essayer avec la clause else
Nous avons appris à connaître `try` et `except`, et maintenant nous allons apprendre à connaître l'instruction `else`.
Lorsque l'instruction `try` ne soulève pas d'exception, le code entre dans le bloc `else`. Il s'agit d'une solution ou d'une option de repli lorsque vous vous attendez à ce qu'une partie de votre script produise une exception. Elle est généralement utilisée dans une brève section d'installation ou de vérification où vous ne voulez pas que certaines erreurs se cachent.
Note : Dans le bloc try-except, vous pouvez utiliser le `else` après toutes les déclarations `except`.
Exemple simple
Nous ajoutons l'instruction `else` à l'exemple ZeroDivisionError. Comme nous pouvons le voir, lorsqu'il n'y a pas d'exception, la fonction print sous l'instruction `else` est exécutée, affichant le résultat.
try:
result = 1/3
except ZeroDivisionError as err:
print(err)
else:
print(f"Your answer is {result}")
Your answer is 0.3333333333333333
IndexError avec l'exemple else
Pour en savoir plus, créons une fonction simple et testons-la dans différents scénarios.
La fonction `find_nth_value` a pour arguments `x` (liste) et `n` (numéro d'index). Nous avons créé un bloc try, except et else pour gérer l'exception IndexError.
x = [5,8,9,13]
def find_nth_value(x,n):
try:
result = x[n]
except IndexError as err:
print(err)
else:
print("Your answer is ", result)
La liste `x` a quatre valeurs et nous allons la tester pour l'indice 6 et l'indice 2.
# Testing
find_nth_value(x,6)
find_nth_value(x,2)
- À n=6, l'exception IndexError a été levée, et nous avons pu voir le message d'erreur par défaut "list index out of range".
- A n=2, aucune exception n'a été levée, et la fonction a imprimé le résultat qui se trouve sous l'instruction `else`.
list index out of range
Your answer is 9
finally Mot clé en Python
Le mot-clé `finally` dans le bloc try-except est toujours exécuté, qu'il y ait ou non une exception. En d'autres termes, le bloc de code `finally` est exécuté après le try, sauf que le bloc else est final. Il est très utile pour nettoyer les ressources et fermer l'objet, en particulier pour fermer les fichiers.
La fonction `divide` est créée pour gérer les exceptions ZeroDivisionError et afficher le résultat lorsqu'il n'y a pas d'exception. Quel que soit le résultat, il s'exécutera toujours `finally` pour imprimer "Code by DataCamp" en couleur verte.
def divide(x,y):
try:
result = x/y
except ZeroDivisionError:
print("Please change 'y' argument to non-zero value")
except:
print("Something went wrong")
else:
print(f"Your answer is {result}")
finally:
print("\033[92m Code by DataCamp\033[00m")
Dans le premier test, nous divisons 1 par 0, ce qui devrait soulever l'exception ZeroDivisionError et afficher le message. Comme nous pouvons le voir, nous avons une ligne supplémentaire après le message d'erreur.
divide(1,0)
Please change 'y' argument to non-zero value
Code by DataCamp
Lorsque nous ajoutons une entrée valide, il affiche le résultat en exécutant les blocages `else` et `finally`.
divide(3,4)
Your answer is 0.75
Code by DataCamp
Au lieu d'un entier, nous avons ajouté une chaîne de caractères comme second argument, ce qui a soulevé une exception, différente de ZeroDivisionError, avec un message différent.
divide(1,'g')
Something went wrong
Code by DataCamp
Dans ces trois scénarios, il y a un point commun. Le code exécute toujours la fonction print sous l'instruction `finally`.
Si vous êtes novice en Python et que vous souhaitez coder comme un vrai programmeur, essayez notre cursus de compétences en programmation Python. Vous apprendrez à écrire du code efficace, les fonctions Python, le génie logiciel, les tests unitaires et la programmation orientée objet.
Gestion des exceptions imbriquées en Python
Nous avons besoin d'une gestion imbriquée des exceptions lorsque nous préparons le programme à gérer plusieurs exceptions dans une séquence. Par exemple, nous pouvons ajouter un autre bloc try-except sous l'instruction `else`. Ainsi, si la première instruction ne soulève pas d'exception, vérifiez la seconde instruction avec l'autre moitié du code.
Modification de la fonction Divide
Nous avons modifié la fonction `divide` de l'exemple précédent et ajouté un bloc try-except imbriqué sous l'instruction `else`. Ainsi, s'il n'y a pas d'AttributeError, il exécutera le `else` et vérifiera le nouveau code pour l'exception ZeroDivisionError.
def divide(x,y):
try:
value = 50
x.append(value)
except AttributeError as atr_err:
print(atr_err)
else:
try:
result = [i / y for i in x]
print( result )
except ZeroDivisionError:
print("Please change 'y' argument to non-zero value")
finally:
print("\033[92m Code by DataCamp\033[00m")
Dans le premier scénario, nous fournissons la liste des 3 valeurs `x` et le dénominateur 3. Le script ajoutera 50 à la liste et divisera la valeur individuelle de la liste par 3, puis affichera le résultat.
x = [40,65,70,87]
divide(x,3)
La fonction a été exécutée avec succès sans soulever d'exception.
[13.333333333333334, 21.666666666666668, 23.333333333333332, 29.0, 16.666666666666668]
Code by DataCamp
Au lieu d'une liste, nous avons fourni un entier au premier argument, ce qui a soulevé une AttributeError.
divide(4,3)
'int' object has no attribute 'append'
Code by DataCamp
Dans le dernier scénario, nous avons fourni la liste mais 0 comme second argument, ce qui a soulevé l'exception ZeroDivisionError dans l'instruction `else`.
divide(x,0)
Please change 'y' argument to non-zero value
Code by DataCamp
Exemple d'édition de fichier
Examinons des exemples plus pratiques de chargement du fichier, d'écriture d'un texte et de fermeture du fichier.
la fonction file_editor sera :
- Vérifiez l'exception FileNotFoundError pour la fonction `open()`.
- Si l'exception extérieure n'est pas levée, il vérifiera l'exception de la fonction `write()`.
- Quoi qu'il en soit, après avoir ouvert le fichier, il le fermera en exécutant l'instruction `finally`.
- Si l'instruction try externe lève l'exception, elle renvoie le message d'erreur avec un chemin d'accès au fichier non valide.
def file_editor(path,text):
try:
data = open(path)
try:
data.write(text)
except:
print("Unable to write the data. Please add an append: 'a' or write: 'w' parameter to the open() function.")
finally:
data.close()
except:
print(f"{path} file is not found!!")
Dans le premier scénario, nous fournissons le chemin d'accès au fichier et le texte.
path = "data.txt"
text = "DataLab: Share your data analysis in a cloud-based environment--no installation required."
file_editor(path,text)
L'exception extérieure est levée.
data.txt file is not found!!
Pour résoudre l'exception du fichier non trouvé, nous devons créer un fichier "data.txt" en utilisant la commande Linux `echo`.
!echo "File by DataCamp" > "data.txt"
Ensuite, relancez la fonction `file_editor()`.
file_editor(path,text)
L'exception interne est levée, car la fonction `write` n'est pas en mesure d'ajouter le texte.
Unable to write the data. Please add an append: 'a' or write: 'w' parameter to the open() function.
Pour résoudre ce problème, nous devons changer la troisième ligne de `data = open(path)` à `data = open(path, 'a')`. Il nous permettra d'ajouter le nouveau texte au fichier.
Après avoir réexécuté la fonction, nous avons ajouté avec succès le texte au fichier.
file_editor(path,text)
La gestion des exceptions imbriquées n'est pas recommandée car elle rend la gestion des exceptions plus complexe ; les développeurs utilisent plutôt plusieurs blocs try-except pour créer une gestion séquentielle simple des exceptions.
Note : vous pouvez également ajouter un bloc try-except imbriqué sous l'instruction `try` ou `except`. Tout dépend de vos besoins.
Lever des exceptions en Python
En tant que développeur Python, vous avez la possibilité de lancer une exception si certaines conditions sont remplies. Il vous permet d'interrompre le programme en fonction de vos besoins.
Pour lancer une exception, nous devons utiliser le mot-clé `raise` suivi d'un nom d'exception.
Exemple de levée d'erreur de valeur
Nous pouvons simplement soulever des exceptions en ajoutant le mot-clé raise dans l'instruction if/else.
Dans l'exemple, nous soulevons l'erreur ValueError si la valeur est supérieure à 1 000. Nous avons changé la valeur en 2,000, ce qui a rendu l'instruction `if` VRAIE et a soulevé ValueError avec le message personnalisé. Le message d'erreur personnalisé vous aide à résoudre rapidement le problème.
value = 2_000
if value > 1_000:
# raise the ValueError
raise ValueError("Please add a value lower than 1,000")
else:
print("Congratulations! You are the winner!!")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
----> 4 raise ValueError("Please add a value lower than 1,000")
5 else:
6 print("Congratulations! You are the winner!!")
ValueError: Please add a value lower than 1,000
Exemple de levée d'une exception
Nous pouvons également lever n'importe quelle exception Python intégrée au hasard si la condition est remplie. Dans notre cas, nous avons levé une "Exception" générique avec le message d'erreur.
if value > 1_000:
# raise the Exception
raise Exception("Please add a value lower than 1,000")
else:
print("Congratulations! You are the winner!!")
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
----> 3 raise Exception("Please add a value lower than 1,000")
4 else:
5 print("Congratulations! You are the winner!!")
Exception: Please add a value lower than 1,000
Exemple de gestion d'une exception levée
Nous pouvons également créer notre propre exception et la gérer en utilisant le bloc try-except.
Dans l'exemple, nous avons ajouté un exemple d'erreur de valeur sous l'instruction `try`.
Comment cela fonctionnera-t-il ? Au lieu de lever l'exception et de terminer le programme, il affichera le message d'erreur que nous avons fourni.
value = 2_000
try:
if value > 1_000:
# raise the ValueError
raise ValueError("Please add a value lower than 1,000")
else:
print("Congratulations! You are the winner!!")
# if false then raise the value error
except ValueError as e:
print(e)
Ce type de gestion des exceptions nous aide à nous préparer aux erreurs qui ne sont pas couvertes par Python et qui sont spécifiques à l'exigence de votre application.
Please add a value lower than 1,000
Conclusion
Les tests unitaires et la gestion des exceptions sont des éléments essentiels de la programmation Python qui permettent à votre code d'être prêt pour la production et à l'abri des erreurs. Dans ce tutoriel, nous avons appris à connaître les exceptions et les erreurs en Python et à les gérer. En outre, nous avons appris à connaître les blocs try-except imbriqués complexes et avons créé des blocs d'exception personnalisés en fonction des besoins.
Ces outils et mécanismes sont essentiels, mais la majeure partie du travail est effectuée par de simples blocs `try` et `except`. Où `try` recherche les exceptions soulevées par le code et `except` gère ces exceptions.
Si cela est déroutant et que vous ne savez pas par où commencer, suivez notre cours Python Data Science Toolbox (Part 1) pour comprendre le cadrage, les fonctions Lambda et la gestion des erreurs. Vous pouvez également vous inscrire au cursus de carrière Python Programmer pour acquérir des compétences professionnelles et devenir un développeur Python professionnel.
Cours de Python
cours
Python intermédiaire
cours