Déboguer avec IDLE – Real Python

By | septembre 9, 2020

Python pas cher

Tout le monde fait des erreurs, même les développeurs professionnels chevronnés! L'interpréteur interactif de Python, IDLE, est assez bon pour détecter les erreurs telles que les erreurs de syntaxe et les erreurs d'exécution, mais il existe un troisième type d'erreur que vous avez peut-être déjà rencontré. Erreurs de logique se produisent lorsqu'un programme par ailleurs valide ne fait pas ce qui était prévu. Les erreurs de logique provoquent des comportements inattendus appelés Bugs. La suppression des bogues s'appelle débogage.

UNE débogueur est un outil qui vous aide à traquer les bogues et à comprendre pourquoi ils se produisent. Savoir comment trouver et corriger les bogues dans votre code est une compétence que vous utiliserez pendant toute votre carrière de codeur!

Utiliser la fenêtre de contrôle de débogage

L'interface principale du débogueur d'IDLE est la fenêtre Debug Control, ou la fenêtre Debug pour faire court. Vous pouvez ouvrir la fenêtre de débogage en sélectionnant Débogage → Débogueur dans le menu de la fenêtre interactive. Allez-y et ouvrez la fenêtre de débogage.

Chaque fois que la fenêtre de débogage est ouverte, la fenêtre interactive s'affiche [DEBUG ON] à côté de l'invite pour indiquer que le débogueur est ouvert. Ouvrez maintenant une nouvelle fenêtre d'éditeur et organisez les trois fenêtres sur votre écran afin de pouvoir toutes les voir simultanément.

Dans cette section, vous apprendrez comment la fenêtre de débogage est organisée, comment parcourir votre code avec le débogueur une ligne à la fois et comment définir des points d'arrêt pour accélérer le processus de débogage.

La fenêtre de contrôle de débogage: un aperçu

Pour voir comment fonctionne le débogueur, vous pouvez commencer par écrire un programme simple sans aucun bogue. Tapez ce qui suit dans la fenêtre de l'éditeur:

    1 pour je dans gamme(1, 4):
    2     j = je * 2
    3     impression(F"je suis je    et j est j")

Enregistrez le fichier, puis laissez la fenêtre de débogage ouverte et appuyez sur F5. Vous remarquerez que l'exécution ne va pas très loin.

La fenêtre de débogage ressemblera à ceci:

Image de la fenêtre de débogage d'IDLE

Notez que le panneau Pile en haut de la fenêtre contient le message suivant:

> «__main__».(), ligne 1: pour i dans la plage (1, 4):

Cela vous dit que ligne 1 (qui contient le code pour i dans la plage (1, 4):) est à propos à exécuter mais n’a pas encore commencé. le module '__main __' () une partie du message fait référence au fait que vous êtes actuellement dans la section principale du programme, par opposition à être, par exemple, dans une définition de fonction avant que le bloc de code principal n'ait été atteint.

Sous le panneau Stack se trouve un panneau Locals qui répertorie des trucs étranges comme __annotations__, __builtins__, __doc__, etc. Ce sont des variables système internes que vous pouvez ignorer pour le moment. Au fur et à mesure de l’exécution de votre programme, vous verrez des variables déclarées dans le code affiché dans cette fenêtre afin que vous puissiez suivre leur valeur.

Il y a cinq boutons situés dans le coin supérieur gauche de la fenêtre de débogage: Aller, Étape, Plus de, En dehors, et Quitter. Ces boutons contrôlent la façon dont le débogueur se déplace dans votre code.

Dans les sections suivantes, vous découvrirez ce que fait chacun de ces boutons, en commençant par Étape.

Le bouton Step

Allez-y et cliquez Étape dans le coin supérieur gauche de la fenêtre de débogage. La fenêtre de débogage change un peu pour ressembler à ceci:

Bouton Python IDLE Step

Il y a deux différences à prendre en compte ici. Tout d'abord, le message du panneau Pile change comme suit:

> «__main__».(), ligne 2: j = i * 2:

À ce point, ligne 1 de votre code s'est exécuté et le débogueur s'est arrêté juste avant de s'exécuter ligne 2.

Le deuxième changement à noter est la nouvelle variable je auquel la valeur est attribuée 1 dans le panneau Locals. C’est parce que le pour boucle dans la première ligne de code a créé la variable je et lui a attribué la valeur 1.

Continuez à frapper le Étape pour parcourir votre code ligne par ligne et observer ce qui se passe dans la fenêtre du débogueur. Lorsque vous arrivez à la file print (f "i est i et j est j"), vous pouvez voir la sortie affichée dans la fenêtre interactive une pièce à la fois.

Plus important encore, vous pouvez suivre les valeurs croissantes de je et j en parcourant le pour boucle. Vous pouvez probablement imaginer à quel point cette fonctionnalité est utile lorsque vous essayez de localiser la source des bogues dans vos programmes. Connaître la valeur de chaque variable à chaque ligne de code peut vous aider à identifier les problèmes.

Points d'arrêt et bouton Go

Souvent, vous savez peut-être que le bogue doit se trouver dans une section particulière de votre code, mais vous ne savez peut-être pas précisément où. Plutôt que de cliquer sur Étape bouton toute la journée, vous pouvez définir un point d'arrêt qui indique au débogueur d'exécuter en continu tout le code jusqu'à ce qu'il atteigne le point d'arrêt.

Les points d'arrêt indiquent au débogueur quand interrompre l'exécution du code afin que vous puissiez jeter un coup d'œil à l'état actuel du programme. Ils ne cassent rien.

Pour définir un point d'arrêt, cliquez avec le bouton droit sur (Ctrl-cliquez sur Mac) sur la ligne de code de votre fenêtre d'édition sur laquelle vous souhaitez faire une pause et sélectionnez Définir le point d'arrêt. IDLE met en évidence la ligne en jaune pour indiquer que votre point d'arrêt a été défini. Pour supprimer un point d'arrêt, cliquez avec le bouton droit sur la ligne avec le point d'arrêt et sélectionnez Effacer le point d'arrêt.

Allez-y et appuyez sur Quitter en haut de la fenêtre de débogage pour désactiver le débogueur pour le moment. Cela ne fermera pas la fenêtre et vous souhaiterez la garder ouverte car vous la réutiliserez dans un instant.

Définissez un point d'arrêt sur la ligne de code avec le impression() déclaration. La fenêtre de l'éditeur devrait maintenant ressembler à ceci:

Point d'arrêt Python IDLE pt. 1

Enregistrez et exécutez le fichier. Tout comme avant, le panneau Stack de la fenêtre Debug indique que le débogueur a démarré et attend d'être exécuté ligne 1. Cliquez sur Aller et regardez ce qui se passe dans la fenêtre de débogage:

Bouton Python IDLE Go pt. 1

Le panneau Stack affiche maintenant le message suivant indiquant qu’il attend l’exécution ligne 3:

> «__main__».(), ligne 3: print (f "i est i et j est j")

Si vous regardez le panneau Locals, vous verrez que les deux variables je et j avoir les valeurs 1 et 2, respectivement. En cliquant Aller, vous avez dit au débogueur d'exécuter votre code en continu jusqu'à ce qu'il atteigne un point d'arrêt ou la fin du programme. presse Aller encore. La fenêtre de débogage ressemble maintenant à ceci:

Bouton Python IDLE Go pt. 2

Voyez-vous ce qui a changé? Le même message que précédemment est affiché dans le panneau Stack, indiquant que le débogueur attend pour s'exécuter ligne 3 encore. Cependant, les valeurs des variables je et j sont maintenant 2 et 4. La fenêtre interactive affiche également la sortie après avoir exécuté la ligne avec impression() la première fois dans la boucle.

Chaque fois que vous appuyez sur Aller , le débogueur exécute le code en continu jusqu'à ce qu'il atteigne le point d'arrêt suivant. Depuis que vous définissez le point d'arrêt sur ligne 3, qui est à l'intérieur du pour loop, le débogueur s'arrête sur cette ligne à chaque fois qu'il parcourt la boucle.

presse Aller une troisième fois. Maintenant je et j avoir les valeurs 3 et 6. Que pensez-vous qu'il va se passer lorsque vous appuyez sur Aller encore une fois? Depuis le pour boucle ne se répète que trois fois, lorsque vous appuyez sur Aller encore une fois, le programme finira de s'exécuter.

Over and Out

le Plus de le bouton fonctionne un peu comme une combinaison de Étape et Aller. Il enjambe une fonction ou une boucle. En d'autres termes, si vous êtes sur le point d'entrer dans une fonction avec le débogueur, vous pouvez toujours exécuter le code de cette fonction sans avoir à parcourir chaque ligne de celui-ci. le Plus de Le bouton vous amène directement au résultat de l'exécution de cette fonction.

De même, si vous êtes déjà dans une fonction ou une boucle, alors le En dehors Le bouton exécute le code restant à l'intérieur de la fonction ou du corps de la boucle, puis s'arrête.

Dans la section suivante, vous allez examiner du code bogué et apprendre à le corriger avec IDLE.

Écraser certains bugs

Maintenant que vous vous êtes familiarisé avec l’utilisation de la fenêtre Contrôle de débogage, examinons un programme bogué.

Le code suivant définit une fonction add_underscores () qui prend un seul objet chaîne mot comme argument et renvoie une nouvelle chaîne contenant une copie de mot avec chaque caractère entouré de traits de soulignement. Par exemple, add_underscores ("python") devrait revenir "_python_".

Voici le code du buggy:

def add_underscores(mot):
    nouveau mot = "_"
    pour je dans gamme(len(mot)):
        nouveau mot = mot[[[[je] + "_"
    revenir nouveau mot

phrase = "Bonjour"
impression(add_underscores(phrase))

Tapez ce code dans la fenêtre de l'éditeur, puis enregistrez le fichier et appuyez sur F5 pour exécuter le programme. Le résultat attendu est _Bonjour_, mais à la place, tout ce que vous voyez est o_, ou la lettre "o" suivi d'un seul trait de soulignement.

Si vous voyez déjà quel est le problème avec le code, ne vous contentez pas de le résoudre. L’objectif de cette section est d’apprendre à utiliser le débogueur IDLE pour identifier le problème.

Si vous ne voyez pas quel est le problème, ne vous inquiétez pas! À la fin de cette section, vous l'aurez trouvé et serez en mesure d'identifier des problèmes similaires dans d'autres codes que vous rencontrez.

Le débogage consiste à résoudre des problèmes, et à mesure que vous deviendrez plus expérimenté, vous développerez vos propres approches. Dans cette section, vous découvrirez une méthode simple en quatre étapes pour vous aider à démarrer:

  1. Devinez quelle section de code peut contenir le bogue.
  2. Définissez un point d'arrêt et inspectez le code en parcourant la section buggy une ligne à la fois, en gardant une trace des variables importantes en cours de route.
  3. Identifiez la ligne de code, le cas échéant, avec l'erreur et apportez une modification pour résoudre le problème.
  4. Répétez les étapes 1 à 3 selon les besoins jusqu'à ce que le code fonctionne comme prévu.

Étape 1: Faites une estimation de l'emplacement du bogue

La première étape consiste à identifier la section de code qui contient probablement le bogue. Vous ne pourrez peut-être pas identifier exactement où se trouve le bogue au début, mais vous pouvez généralement faire une estimation raisonnable de la section de votre code qui contient une erreur.

Notez que le programme est divisé en deux sections distinctes: une définition de fonction (où add_underscores () est défini), et un bloc de code principal qui définit une variable phrase avec la valeur "Bonjour" puis imprime le résultat de l'appel add_underscores (phrase).

Regardez la section principale:

phrase = "Bonjour"
impression(add_underscores(phrase))

Pensez-vous que le problème pourrait être ici? Ça ne ressemble pas à ça, non? Tout sur ces deux lignes de code semble bon. Donc, le problème doit être dans la définition de la fonction:

def add_underscores(mot):
    nouveau mot = "_"
    pour je dans gamme(len(mot)):
        nouveau mot = mot[[[[je] + "_"
    revenir nouveau mot

La première ligne de code à l'intérieur de la fonction crée une variable nouveau mot avec la valeur "_". Vous êtes tous bien là-bas, vous pouvez donc conclure que le problème se situe quelque part dans le corps du pour boucle.

Étape 2: définir un point d'arrêt et inspecter le code

Maintenant que vous avez identifié l'emplacement du bogue, définissez un point d'arrêt au début de la pour boucle afin que vous puissiez tracer exactement ce qui se passe dans le code avec la fenêtre de débogage:

Point d'arrêt Python IDLE pt. 2

Ouvrez la fenêtre de débogage et exécutez le fichier. L'exécution s'arrête toujours sur la toute première ligne qu'elle voit, qui est la définition de la fonction.

presse Aller pour parcourir le code jusqu'à ce que le point d'arrêt soit rencontré. La fenêtre de débogage ressemblera maintenant à ceci:

Fenêtre de débogage Python IDLE pt. 1

À ce stade, le code est mis en pause juste avant d'entrer le pour boucle dans le add_underscores () fonction. Notez que deux variables locales, mot et nouveau mot, sont affichés dans le panneau Locals. Actuellement, mot a la valeur "Bonjour" et nouveau mot a la valeur "_" comme prévu.

Cliquez sur Étape une fois pour entrer dans pour boucle. La fenêtre de débogage change et une nouvelle variable je avec la valeur 0 s'affiche dans le panneau Locals:

Fenêtre de débogage Python IDLE pt. 2

je est le compteur utilisé dans le pour boucle, et vous pouvez l'utiliser pour garder une trace de l'itération du pour boucle que vous regardez actuellement.

Cliquez sur Étape encore une fois. Si vous regardez le panneau Locals, vous verrez que la variable nouveau mot a pris de la valeur "h_":

Fenêtre de débogage Python IDLE pt. 3

Ce n’est pas juste. Initialement, nouveau mot avait la valeur "_", et à la deuxième itération du pour boucle, il devrait maintenant avoir la valeur "_h_". Si vous cliquez sur Étape encore quelques fois, alors vous verrez que nouveau mot se prépare à e_, puis l_, etc.

Étape 3: Identifiez l'erreur et essayez de la corriger

La conclusion que vous pouvez faire à ce stade est que, à chaque itération du pour boucle, nouveau mot est écrasé par le caractère suivant de la chaîne "Bonjour" et un trait de soulignement à la fin. Puisqu'il n'y a qu'une seule ligne de code dans le pour boucle, vous savez que le problème doit être avec le code suivant:

Regardez attentivement la ligne. Il dit à Python d'obtenir le prochain caractère de mot, collez un trait de soulignement à la fin de celui-ci, et affectez cette nouvelle chaîne à la variable nouveau mot. C'est exactement le comportement dont vous avez été témoin en parcourant le pour boucle!

Pour résoudre le problème, vous devez dire à Python de concaténer la chaîne mot[i] + "_" à la valeur existante de nouveau mot. presse Quitter dans la fenêtre de débogage, mais ne fermez pas encore la fenêtre. Ouvrez la fenêtre de l'éditeur et modifiez la ligne à l'intérieur du pour boucle vers ce qui suit:

nouveau mot = nouveau mot + mot[[[[je] + "_"

Étape 4: Répétez les étapes 1 à 3 jusqu'à ce que le bogue disparaisse

Enregistrez les nouvelles modifications apportées au programme et réexécutez-le. Dans la fenêtre de débogage, appuyez sur Aller pour exécuter le code jusqu'au point d'arrêt.

Le programme s'arrête juste avant d'entrer le pour boucle dans add_underscores (). presse Étape et regardez ce qui arrive au nouveau mot variable à chaque itération. Succès! Tout fonctionne comme prévu!

Votre première tentative de correction du bogue a fonctionné, vous n'avez donc plus besoin de répéter les étapes 1 à 3. Ce ne sera pas toujours le cas. Parfois, vous devrez répéter le processus plusieurs fois avant de corriger un bogue.

Méthodes alternatives pour trouver des bogues

Utiliser un débogueur peut être délicat et prendre du temps, mais c'est le moyen le plus fiable de trouver des bogues dans votre code. Cependant, les débogueurs ne sont pas toujours disponibles. Les systèmes dotés de ressources limitées, comme les petits appareils Internet des objets, ne disposent souvent pas de débogueur intégré.

Dans de telles situations, vous pouvez utiliser débogage d'impression pour trouver des bogues dans votre code. Utilisation du débogage d'impression impression() pour afficher du texte dans la console qui indique où le programme s’exécute et quel est l’état des variables du programme à certains points du code.

Par exemple, au lieu de déboguer le programme précédent avec la fenêtre de débogage, vous pouvez ajouter la ligne suivante à la fin du pour boucle dans add_underscores ():

impression(F"i = je; nouveau_mot = nouveau mot")

Le code modifié ressemblerait alors à ceci:

def add_underscores(mot):
    nouveau mot = "_"
    pour je dans gamme(len(mot)):
        nouveau mot = mot[[[[je] + "_"
        impression(F"i = je; nouveau_mot = nouveau mot")
    revenir nouveau mot

phrase = "Bonjour"
impression(add_underscores(phrase))

Lorsque vous exécutez le fichier, la fenêtre interactive affiche la sortie suivante:

i = 0; nouveau_mot = h_
i = 1; nouveau_mot = e_
i = 2; nouveau_mot = l_
i = 3; nouveau_mot = l_
i = 4; nouveau_mot = o_
o_

Cela vous montre quelle est la valeur de nouveau mot est à chaque itération du pour boucle. La dernière ligne ne contenant qu'un seul trait de soulignement est le résultat de l'exécution print (add_underscore (phrase)) à la fin du programme.

En regardant la sortie ci-dessus, vous pouvez arriver à la même conclusion que lors du débogage avec la fenêtre de débogage. Le problème est que nouveau mot est écrasé à chaque itération.

Le débogage d'impression fonctionne, mais il présente plusieurs inconvénients par rapport au débogage avec un débogueur. Tout d'abord, vous devez exécuter l'intégralité de votre programme chaque fois que vous souhaitez inspecter les valeurs de vos variables. Cela peut être une énorme perte de temps par rapport à l'utilisation de points d'arrêt. Vous devez également vous rappeler de supprimer ces impression() appels de fonction à partir de votre code lorsque vous avez terminé le débogage!

L’exemple de boucle de cette section peut être un bon exemple pour illustrer le processus de débogage, mais ce n’est pas le meilleur exemple de code Pythonic. L'utilisation de l'index je est un cadeau qu'il pourrait y avoir une meilleure façon d'écrire la boucle.

Une façon d'améliorer cette boucle consiste à parcourir les caractères dans mot directement. Voici une façon de procéder:

def add_underscores(mot):
    nouveau mot = "_"
    pour lettre dans mot:
        nouveau mot = nouveau mot + lettre + "_"
    revenir nouveau mot

Le processus de réécriture du code existant pour être plus propre, plus facile à lire et à comprendre, ou plus conforme aux normes fixées par une équipe est appelé refactorisation. Nous ne parlerons pas de la refactorisation dans ce didacticiel, mais c'est un élément essentiel de la rédaction d'un code de qualité professionnelle.

Conclusion: débogage Python avec IDLE

C'est tout! Vous savez maintenant tout sur le débogage à l'aide de la fenêtre de débogage d'IDLE. Vous pouvez utiliser les principes de base que vous avez utilisés ici avec un certain nombre d'outils de débogage différents. Vous êtes maintenant bien équipé pour commencer le débogage de votre code Python.

Dans ce didacticiel, vous avez appris:

  • Comment utiliser IDLE Contrôle de débogage fenêtre pour inspecter les valeurs des variables
  • Comment insérer points d'arrêt pour examiner de plus près le fonctionnement de votre code
  • Comment utiliser le Étape, Aller, Plus de, et En dehors boutons pour traquer les bogues ligne par ligne

Vous avez également un peu de pratique pour déboguer une fonction défectueuse à l'aide d'un processus en quatre étapes pour identifier et supprimer les bogues:

  1. Devinez où se trouve le bogue.
  2. Définissez un point d'arrêt et inspectez le code.
  3. Identifiez l'erreur et essayez de la corriger.
  4. Répétez les étapes 1 à 3 jusqu'à ce que l'erreur soit corrigée.

Le débogage est autant un art qu'une science. La seule façon de maîtriser le débogage est de s'entraîner beaucoup! Une façon de s'entraîner est d'ouvrir la fenêtre Contrôle de débogage et de l'utiliser pour parcourir votre code tout en travaillant sur les exercices et les défis que vous trouvez dans d'autres Vrai Python tutoriels.

Pour plus d'informations sur le débogage du code Python, consultez Débogage Python avec Pdb. Si vous avez apprécié ce que vous avez appris dans cet exemple de Principes de base de Python: une introduction pratique à Python 3, puis assurez-vous de consulter le reste du livre.