Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Erreurs, enregistrement et débogage

Handle error types and troubleshoot (debug). For interactive reading and executing code blocks Binder and find b02-pyerror.ipynb, or install Python and JupyterLab locally.

Erreurs et exceptions

Types d’erreur

L’erreur est humaine et Python nous aide à trouver nos erreurs en fournissant des descriptions de type error. Voici une liste d’erreurs courantes qui peuvent survenir lors de l’écriture/exécution du code Python :

Error TypeDescriptionExample
KeyErrorA mapping key is not found.May occur when referencing a non-existing dictionary key.
ImportErrorImporting a module that does not existimport the-almighty-module
IndentationErrorThe code block indentation is not correct.See code style descriptions
IndexErrorAn index outside the range of a variable is used.nums = [1, 2]; print(nums[2])
NameErrorAn undefined variable is referenced.print(a)
TypeErrorIncompatible data types and/or operators are used together."my_string" / 10
ValueErrorRight data type, but an inappropriate value.int(input("Number:")) answered with t
ZeroDivisionErrorDivision by zero.3 / 0

Cependant, il y a beaucoup d’autres types d’erreurs qui peuvent se produire, et les développeurs de Python maintiennent une description complète des exceptions intégrées sur le site Web de documentation de Python.

Traitement des exceptions avec try - except

try et except mots-clés testent un bloc de code et si celui-ci s’écrase, un exception est soulevé, mais le script lui-même ne s’écrasera pas (à moins de définir autrement dans l’énoncé except). La structure de base est :

try:
    # code block
except ErrorType:
    print("Error / warning message.")

Le ErrorType est techniquement pas nécessaire (c.-à-d., except: fait le travail, aussi), mais ajouter un ErrorType est une bonne pratique pour permettre un débogage efficace ou faire comprendre aux autres utilisateurs l’origine d’une erreur ou d’un avertissement. L’exemple suivant illustre l’implémentation d’un ValueError dans un script de console interactif qui exige que les utilisateurs saisissent une valeur entière.

try:
    x = int(input("How many scoops of ice cream do you want? "))
except ValueError:
    print("What's that? sorry, please try again.")
How many scoops of ice cream do you want?  4

La déclaration try peut également avoir une clause else, qui ne fonctionne que si le bloc try ne soulève aucune exception (ici en utilisant des fonctions d’aide telles que key_not_found ou handle_value):

try:
    value = a_dictionary[key]
except KeyError:
    return key_not_found(key)
else:
    return handle_value(value)

Déclaration pass

Lorsque nous commençons à écrire du code, nous sommes souvent confrontés à un défi complexe qui ne peut pas être codé à la fois. Pour ces défis, Python nous aide avec l’instruction pass qui permet l’implémentation de blocs de code vides (évitez) et l’exécution progressive du code (c.-à-d., pour déboguer le code). De plus, les définitions de type d’erreur ci-dessus aident à comprendre les erreurs que nous avons faites dans le code déjà écrit. Par exemple, pour définir plus tard ce qui se passe lorsque Python entre dans un NameError, une déclaration pass peut être implémentée comme suit :

try:
    a = 5
    c = a + b # we want to define b later on with a complex formula
except NameError:
    pass # we know that we did not define b yet

Exploitation forestière

La fonction print() est utile pour imprimer les variables ou la progression du calcul sur la console (pas trop souvent, l’impression prend du temps et ralentit les calculs). Cependant, pour la déclaration robuste d’erreurs ou d’autres messages importants, un fichier journal représente un meilleur choix. Qu’est-ce qu’un fichier journal ou l’acte de l’enregistrement? Nous connaissons les journaux de bord des découvreurs ou aventuriers, qui écrivent leurs expériences ordonnées par des dates. De même, un code peut écrire (log) ses « expériences », mais dans un fichier au lieu d’un livre. À cette fin, Python a la norme loging library. Pour le moment, il suffit de savoir que la bibliothèque logging peut être importée dans n’importe quel script Python avec import logging (plus d’informations sur les paquets, les modules et les bibliothèques sont fournis dans la section Paquets, modules et bibliothèques).

Le bloc de code ci-dessous importe le module logging et utilise les paramètres de mot-clé suivants pour définir le logging.basicConfig:

  • filename="my-logfile.log" fait écrire des messages dans un fichier nommé "my-logfile.log" dans le même répertoire que le script Python.

  • format="%(asctime)s - %(message)s définit le format de l’enregistrement à YYYY-MM-DD HH:MM:SS.sss - Message texte (plus d’options de format sont énumérées dans le Python docs).

  • filemode="w" écrase les messages précédents dans le fichier journal (supprimer cet argument pour ajouter des messages au lieu d’écraser).

  • level=logging.DEBUG définit la gravité des messages écrits dans le fichier journal, où DEBUG est adéquat pour les diagnostics de problèmes dans les codes; les autres niveaux de gravité de l’événement sont:

    • logging.INFO pour écrire tous les messages de confirmation des événements qui ont fonctionné comme prévu.

    • logging.WARNING (default) pour indiquer quand un événement inattendu s’est produit ou quand un événement peut causer une erreur à l’avenir (par exemple, en raison d’un espace disque insuffisant).

    • logging.ERROR pour signaler de graves problèmes qui font planter le code ou ne pas produire le résultat souhaité.

    • logging.CRITICAL est un indicateur de problème grave plus large, où le programme lui-même peut ne pas être en mesure de continuer à fonctionner (par exemple, non seulement le code, mais aussi Python plante).

Jusqu’ici, les messages ne sont écrits que dans le fichier journal, mais nous ne pouvons voir aucun message dans la console. Pour activer l’enregistrement simultané dans un fichier journal et la console (terminal Python), utilisez logging.getLogger().addHandler(logging.StreamHandler()) qui ajoute un gestionnaire de flux io.

Pour écrire un message au fichier journal (et au terminal Python), utilisez

  • logging.debug("message") pour les diagnostics de code,

  • logging.info("message") for progress information (just like we used print("message") before),

  • logging.warning("warning-message") pour la documentation imprévue de l’événement (sans interruption du programme),

  • logging.error("error-message") pour les erreurs qui entraînent un dysfonctionnement du code, et

  • logging.critical("message") pour les erreurs critiques qui peuvent conduire à des pannes de programme (Python).

Les messages d’avertissement, d’erreur* et de critique* doivent être mis en œuvre dans des situations exceptionnelles (voir ci-dessus try - except déclarations).

À la fin d’un script, l’enregistrement doit être arrêté avec logging.shutdown() car sinon le fichier journal est verrouillé par Python et le noyau de Python doit être arrêté pour apporter des modifications (par exemple, supprimer) au fichier journal.

import logging

logging.basicConfig(filename="my-logfile.log", format="%(asctime)s - %(message)s", filemode="w", level=logging.DEBUG)
logging.getLogger().addHandler(logging.StreamHandler())
logging.debug("This message is logged to the file.")
logging.info("Less severe information is also logged to the file.")
logging.warning("Warning messages are logged, too.")

a = "text"

try:
    logging.info(str(a**2))
except TypeError:
    logging.error("The variable is not numeric.")

# stop logging
logging.shutdown()
This message is logged to the file.
Less severe information is also logged to the file.
Warning messages are logged, too.
The variable is not numeric.

Et voici comment my-logfile.log ressemble à :

2025-05-25 18:51:46,657 - This message is logged to the file.
2025-05-25 18:51:46,666 - Less severe information is also logged to the file.
2025-05-25 18:51:46,667 - Warning messages are logged, too.
2025-05-25 18:51:46,669 - The variable is not numeric.

Les événements peuvent également être documentés en injectant un objet enregistreur avec logger = logging.getLogger(__name__). Cette solution favorable est recommandée pour le codage avancé tel que l’écriture d’un nouveau (custom) Python library (lire plus dans les documents Python sur log](https://docs.python.org/3/howto/logging.html#advanced-logging-tutorial)). Un script exemple avec un enregistreur plus sophistiqué est fourni avec le script Logger à l’emplacement du cours.

Déboguement

Une fois que vous avez écrit un code plus ou moins complexe, la question ultime est : Va-t-il fonctionner ? La réponse décevante est non (dans la plupart des cas), mais il y a un remède appelé debugging, qui est l’acte de supprimer les bogues (erreurs) du code. Cependant, de grands blocs de code peuvent être un cauchemar pour le débogage et cette section fournit quelques principes pour réduire le facteur de scarosité que le débogage peut impliquer.

Utiliser des exceptions précisément

Embrassez les blocs de code critiques précisément avec try - except mots clés et erreurs possibles. Cela aidera plus tard à identifier les origines possibles d’erreurs.

Utiliser les noms de variables descriptifs

Donnez des variables, des fonctions et d’autres objets des noms descriptifs et significatifs. Les abréviations seront toujours nécessaires, mais elles doivent être descriptives (p. ex., utiliser des acronymes). Pour les variables et les fonctions, n’utilisez que des petites lettres. Pour les cours, utilisez CamelCase.

Traiter les erreurs

Si un message d’erreur est soulevé, lisez le message d’erreur en profondeur et plusieurs fois pour comprendre l’origine de l’erreur. Les messages d’erreur indiquent souvent le script particulier et le numéro de ligne où l’erreur a été soulevée. Dans le cas où l’erreur n’est pas un résultat apparent de types de données détournés ou de l’un des messages d’erreur ci-dessus (par exemple, une erreur soulevée dans un module ou un paquet externe), utilisez votre moteur de recherche préféré pour résoudre l’erreur.

Vérifier la sortie

Le fait que le code fonctionne n’implique pas intrinsèquement que le résultat (output) est la sortie souhaitée. Par conséquent, exécutez le code avec des paramètres d’entrée qui produisent la sortie existante d’une autre source (p. ex. calcul manuel) et vérifiez que la sortie produite par le code correspond à la sortie existante (désirée).

Code avec une approche structurée

Pensez à la structure du code avant de commencer par poinçonner un tas de blocs de code et de les stocker dans certains fichiers Python. Les diagrammes de structure et/ou de comportement aident à élaborer un cadre de code sophistiqué. Les développeurs du langage de modélisation unifié (UML) fournissent des lignes directrices solides pour développer la structure et le comportement UML diagrams en génie logiciel.

Solutions de rechange souples

Expliquez votre problème à un ami ou parlez-le à haute voix : Rephrasing et essayer d’expliquer un problème à une autre personne (même si ce n’est qu’une personne imaginaire ou un groupe de personnes) représente souvent un trouble lui-même.

Marchez, dormez sur le problème, ou faites d’autres choses avec l’occupation du cerveau bas. Pendant que vous faites face à d’autres choses, votre cerveau continue de penser au problème (Wikipedia a même consacré une page à ce soi-disant processus de incubation].

Vérification de la réussite en apprentissage

Prenez le test de réussite d’apprentissage pour ce carnet Jupyter.