Compréhension complète du débogage Python

déboguer

Le débogage est l'une des compétences les plus importantes pour les développeurs. En déboguant, vous pouvez identifier les erreurs et trouver des bogues dans votre programme. Python fournit une variété d'outils et de packages de débogage (également appelés débogueurs). Je vais vous présenter comment les utiliser.

Déboguer avec pdb

"Pdb" est un outil de débogage de bibliothèque Python standard qui fournit des capacités de débogage de code source interactif pour les programmes Python. .. L'utilisation est le langage C "gdb" C'est pareil. La fonction principale de pdb est [" breakpoint "](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AC%E3%83%BC%E3%82 Installation de% AF% E3% 83% 9D% E3% 82% A4% E3% 83% B3% E3% 83% 88), "Step execution" /word15249.html), "[Stack Frame](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%AB%E3%82%B9%E3 % 82% BF% E3% 83% 83% E3% 82% AF) "vérifier, changer la valeur de la variable dynamiquement, etc. pdb fournit des commandes d'opération de débogage couramment utilisées.

commander 短縮commander La description
break b Définition des points d'arrêt;b <Nombre de lignes>で指定Nombre de lignesにブレークポイントを設置できる
continue cont/c Reprendre l'exécution jusqu'au prochain point d'arrêt
next n Exécutez la ligne suivante; la ligne suivante ne rentre pas à l'intérieur s'il s'agit d'un sous-programme (fonction, etc.)
step s Exécutez la ligne suivante; la ligne suivante entre à l'intérieur s'il s'agit d'un sous-programme (fonction, etc.)
where bt/w "Trace de la pile"Spectacle
enable - Activer les points d'arrêt désactivés
disable - Désactiver les points d'arrêt activés
pp/p - p <Nom de variable>Imprimer les variables avec
list l Afficher les sources autour de la ligne actuelle (vous pouvez afficher une plus large gamme de sources avec la commande ll)
up u Déplacer vers le cadre de pile ci-dessus
down d Déplacer vers le cadre de pile ci-dessous
restart run Redémarrez le débogage
args a Imprimer les arguments de la fonction
clear cl Supprimez tous les points d'arrêt;cl <nombre>で指定nombreのブレークポイントを削除できる
return r Courir jusqu'à la fin de la fonction
help h h <Nom de la commande>Afficher l'aide sur les commandes avec
quit q Quitter le débogage

Vous pouvez lancer le débogueur pdb de deux manières. La première consiste à spécifier le module pdb avec un argument de ligne de commande et à démarrer le fichier Python.

python -m pdb test_pdp.py

L'autre consiste à définir des points d'arrêt dans le module pdb`` set_trace dans votre code Python. Le programme suspend et lance automatiquement le débogueur pdb lorsqu'il s'exécute vers le point d'arrêt.

import pdb


def factorial(n, sum=0):
    if n == 0:
        return sum

    pdb.set_trace()
    sum += n
    print(sum)
    return factorial(n-1, sum)


if __name__ == '__main__':
    factorial(5)

Il n'y a pas de différence particulière entre les deux méthodes, mais le choix se fait au cas par cas. Si votre code est court, vous pouvez démarrer pdb avec la méthode d'argument de ligne de commande. D'un autre côté, quand il s'agit de grands programmes, il est plus facile de définir des points d'arrêt à l'avance avec set_trace où vous voulez déboguer.

Une fois le débogueur pdb lancé, vous pourrez déboguer avec la commande ci-dessus. L'exemple ci-dessous est un débogage de la fonction de hiérarchie récursive de queue. Tout d'abord, j'ai vérifié la pile d'appels de la fonction avec bt et j'ai regardé le code Python avec liste. Ensuite, j'ai imprimé la valeur de «somme» avec «p» et j'ai suivi le «retour» récursif avec «r». Et enfin, j'ai terminé le débogage avec q.

kaito@MacBook-Pro debug % python factorial.py 
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
-> sum += n
(Pdb) bt
  /Users/kaito/Desktop/debug/factorial.py(15)<module>()
-> factorial(5)
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
-> sum += n
(Pdb) list
  4     def factorial(n, sum=0):
  5         if n == 0:
  6             return sum
  7  
  8         pdb.set_trace()
  9  ->     sum += n
 10         print(sum)
 11         return factorial(n-1, sum)
 12  
 13  
 14     if __name__ == '__main__':
-> sum += n
(Pdb) p sum
0
-> sum += n
(Pdb) r
5
> /Users/kaito/Desktop/fluent python/debug/factorial.py(9)factorial()
-> sum += n
(Pdb) r
9
> /Users/kaito/Desktop/fluent python/debug/factorial.py(9)factorial()
-> sum += n
(Pdb) r
12
> /Users/kaito/Desktop/fluent python/debug/factorial.py(9)factorial()
-> sum += n
(Pdb) r
14
> /Users/kaito/Desktop/fluent python/debug/factorial.py(9)factorial()
-> sum += n
(Pdb) r
15
--Return--
> /Users/kaito/Desktop/debug/factorial.py(11)factorial()->15
-> return factorial(n-1, sum)
(Pdb) q
Traceback (most recent call last):
...

Si la sortie de pdb semble un peu simple, il y a aussi un paquet appelé ʻipdb qui nettoiera la sortie. C'est la même image que ʻipython qui nettoie l'environnement REPL. L'API est la même, vous pouvez donc l'utiliser telle quelle en remplaçant ʻimport pdb par ʻimport ipdb as pdb.

(tensorflow) kaito@MacBook-Pro debug % python factorial.py
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
      8     ipdb.set_trace()
----> 9     sum += n
     10     print(sum)

ipdb> r                                                                                   
5
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
      8     ipdb.set_trace()
----> 9     sum += n
     10     print(sum)

ipdb> r                                                                                   
9
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
      8     ipdb.set_trace()
----> 9     sum += n
     10     print(sum)

ipdb> r                                                                                   
12
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
      8     ipdb.set_trace()
----> 9     sum += n
     10     print(sum)

ipdb> r                                                                                   
14
> /Users/kaito/Desktop/debug/factorial.py(9)factorial()
      8     ipdb.set_trace()
----> 9     sum += n
     10     print(sum)

ipdb> r                                                                                   
15
--Return--
15
> /Users/kaito/Desktop/debug/factorial.py(11)factorial()
     10     print(sum)
---> 11     return factorial(n-1, sum)
     12 

ipdb> q                                                                                   
Exiting Debugger.

C'est en fait coloré et plus beau.

En plus de ʻipub`, il existe également un package qui peut être débogué avec un navigateur appelé "web-pdb". Et l'API est la même que «pdb». En tant qu'image, vous pouvez le voir en regardant la figure ci-dessous.

Aussi, si vous aimez vim, consultez "PuDB" dans le débogueur CUI. L'image est comme indiqué dans la figure ci-dessous. C'est irrésistible pour les amateurs de CUI. De plus, concernant son utilisation, nous vous recommandons [l'article] de @ Kernel_OGSun (https://qiita.com/Kernel_OGSun/items/144c8502ce2eaa5e4410).

Déboguer avec point d'arrêt

Une fonction intégrée appelée breakpoint a été ajoutée à partir de Python 3.7 (PEP 553). L'utilisation de base est la suivante.

def factorial(n, sum=0):
    if n == 0:
        return sum

    breakpoint()
    sum += n
    print(sum)
    return factorial(n-1, sum)


if __name__ == '__main__':
    factorial(5)

Par défaut, c'est exactement la même chose que ʻimport pdb; pdb.set_trace () `.

En tant qu'utilisation avancée, vous pouvez ajouter diverses fonctions en définissant une variable d'environnement appelée PYTHONBREAKPOINT. Par exemple, vous pouvez désactiver le débogage avec PYTHONBREAKPOINT = 0, éliminant ainsi le besoin d'effacer chaque point d'arrêt () dans votre code.

Ensuite, en définissant PYTHONBREAKPOINT = 'importable.callable', ʻimportable.callable sera ʻimport et callable sera appelé. Par exemple, vous pouvez utiliser web-pdb comme suit:

PYTHONBREAKPOINT='web_pdb.set_trace' python test_pdb.py

C'est très pratique car vous pouvez remplacer le débogueur sans changer une seule ligne de code Python en ne modifiant que les variables d'environnement.

Déboguer avec Visual Studio Code

Il est très facile de déboguer avec VSCode.

Tout d'abord, cliquez sur l'icône de bogue dans la barre d'outils de gauche. Dans un premier temps, vous devez créer launch.json, mais les valeurs par défaut sont plutôt bonnes.                                                                                                        Screen Shot 2020-09-30 at 23.25.01.png

Vous pouvez ensuite définir un point d'arrêt en cliquant à côté du numéro de ligne.                                                                             Screen Shot 2020-09-30 at 23.34.09.png

Cliquez ensuite sur Démarrer le débogage pour l'exécuter.                                                                             Screen Shot 2020-09-30 at 23.39.44.png

Ensuite, l'écran suivant s'affiche. Screen Shot 2020-09-30 at 23.42.46.png

Vous pouvez effectuer le débogage à l'aide du bouton en haut à droite.                                                       Screen Shot 2020-09-30 at 23.57.30.png

«Step Over» est une fonction équivalente à «next» de «pdb». De plus, «Step In» est «step» de «pdb» et «Step Out» est «return». L'interface graphique est facile à utiliser.

Déboguer avec PyCharm

En gros, c'est la même interface que VS Code. Screen Shot 2020-10-01 at 0.05.49.png

Commencez le débogage avec l'icône de bogue en haut à droite et terminez par l'icône carrée.                                                                             Screen Shot 2020-10-01 at 0.07.25.png

Lorsque vous souhaitez effectuer le débogage, vous pouvez principalement utiliser ce bouton.                                                                             Screen Shot 2020-10-01 at 0.10.34.png

Appuyez sur la boule Futako à gauche pour accéder à l'écran ci-dessous. Il est très pratique de pouvoir définir les conditions pour entrer le point d'arrêt avec Condition. Screen Shot 2020-10-01 at 0.14.37.png

Appuyez sur l'icône de la calculatrice à l'extrême droite pour accéder à l'écran ci-dessous. Vous pouvez vérifier les variables, etc. Screen Shot 2020-10-01 at 0.16.31.png

Résumé

Nous avons beaucoup vu sur le débogage Python. Tout d'abord, la bibliothèque standard «pdb» et ses dérivés. En tant que développeur Python, retenons pdb pour le moment. J'ai également regardé VS Code et les débogueurs GUI de PyCharm. C'est fondamentalement très facile à utiliser, donc si vous connaissez pdb, vous pourrez l'utiliser tout de suite. Bien entendu, l'utilisation avancée n'a pas d'autre choix que d'acquérir de l'expérience dans la pratique.

Recommended Posts

Compréhension complète du débogage Python
Compréhension complète du threading Python et du multitraitement
Traitement asynchrone de Python ~ Comprenez parfaitement async et attendez ~
[Python] Comprendre le potentiel_field_planning de Python Robotics
débogage python DS
Comprendre Python Coroutine
Jeu de main Python (calculé plein de mordred)
Conseils de débogage Python
Bases de python ①
Copie de python
Comprendre l'auto python
Introduction de Python
Compréhension complète des concepts de Bellmanford et Dyxtra
Compréhension facile de Python pour les tableaux et (pour les super débutants)
[Python] Une compréhension approximative du module de journalisation
[Python] Une compréhension approximative des itérables, des itérateurs et des générateurs
[Python] Opération d'énumération
Liste des modules python
Unification de l'environnement Python
Copie des préférences python
[Python] Débogage super utile
Principes de base du grattage Python
[python] comportement d'argmax
Utilisation des locaux Python ()
le zen de Python
Installation de Python 3.3 rc1
Mémorandum elasticsearch_dsl
recherche complète de bits python
# 4 [python] Bases des fonctions
Connaissance de base de Python
Anecdotes sobres de python3
Résumé des arguments Python
Bases de python: sortie
Installation de matplotlib (Python 3.3.2)
Application de Python 3 vars
Divers traitements de Python
Obtenez une compréhension abstraite des modules et des packages Python
[Python] Utilisation correcte de la carte
[Python] Débogage plus efficace!
résumé lié à l'opération de fichier python
Résumé des opérations de liste Python3
Python - Démarrage rapide de la journalisation
Recommandation de la bibliothèque binpacking de python
[python] Valeur de l'objet fonction (?)
Mise à jour automatique du module Python
Python - Vérifiez le type de valeurs
Compréhension complète de la fonction numpy.pad
[Python] L'origine du nom de la fonction python
À propos de divers encodages de Python 3
Jugement d'équivalence d'objet en Python
Introduction d'activités appliquant Python
Installer plusieurs versions de Python
Mise à niveau de python Anaconda
Manipulation de python sur mac
python: principes de base de l'utilisation de scikit-learn ①
Recherche de bits complète avec Python
2.x, 3.x code de caractères des séries python
Paiza Python Primer 8: Comprendre les classes
Comparaison de 4 types de frameworks Web Python