Accéder au contenu principal

Gestion des exceptions et des erreurs en Python

Les erreurs et les exceptions peuvent entraîner l'échec du programme ou un comportement inattendu, et Python est livré avec un ensemble robuste d'outils permettant d'améliorer la stabilité du code.
Actualisé 14 nov. 2024  · 21 min de lecture

try except else finally process 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 :

  1. AssertionError : levée lorsque l'affirmation échoue.
  2. Erreur EOFError : levée lorsque la fonction input() rencontre la condition de fin de fichier.
  3. AttributeError : levée lorsque l'attribution ou la référence d'un attribut échoue.
  4. TabError : levée lorsque les indentations sont constituées de tabulations ou d'espaces incohérents. 
  5. ImportError : levée lorsque l'importation du module échoue. 
  6. IndexError : se produit lorsque l'index d'une séquence est en dehors de la plage.
  7. KeyboardInterrupt : levée lorsque l'utilisateur saisit des touches d'interruption (Ctrl + C ou Suppr).
  8. RuntimeError : se produit lorsqu'une erreur n'entre dans aucune catégorie. 
  9. NameError : levée lorsqu'une variable n'est pas trouvée dans la portée locale ou globale. 
  10. MemoryError : levée lorsque les programmes manquent de mémoire. 
  11. Erreur de valeur : se produit lorsque l'opération ou la fonction reçoit un argument du bon type mais de la mauvaise valeur. 
  12. ZeroDivisionError : levée lorsque vous divisez une valeur ou une variable par zéro. 
  13. SyntaxError : levée par l'analyseur syntaxique lorsque la syntaxe Python est incorrecte. 
  14. IndentationError : se produit lorsque l'indentation est incorrecte.
  15. 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`.  

  1. Exécutez le code sous l'instruction `try`.
  2. 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. 

instruction try except en Python

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`. 

essayer avec la clause else en Python

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.

Le mot-clé finally en Python

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"

édition de fichiers dans l'espace de travail

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)

capture d'écran de l'édition de fichiers dans l'espace de travail

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. 



Sujets

Cours de Python

Certification disponible

cours

Introduction à Python

4 hr
5.7M
Maîtrisez les bases de l'analyse de données avec Python en seulement quatre heures. Ce cours en ligne vous présentera l'interface Python et explorera les packages populaires.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow