Vollständiges Verständnis des Python-Debuggens

debuggen

Das Debuggen ist eine der wichtigsten Fähigkeiten für Entwickler. Durch das Debuggen können Sie Fehler lokalisieren und Fehler in Ihrem Programm finden. Python bietet eine Vielzahl von Debugging-Tools und -Paketen (auch als Debugger bezeichnet). Ich werde vorstellen, wie man diese benutzt.

Debuggen mit pdb

"Pdb" ist ein Standard-Debugging-Tool für Python-Bibliotheken, das interaktive Quellcode-Debugging-Funktionen für Python-Programme bietet. .. Die Verwendung ist C-Sprache "gdb" Das ist ähnlich. Die Hauptfunktion von pdb ist [" Haltepunkt "](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AC%E3%83%BC%E3%82 Installation von% AF% E3% 83% 9D% E3% 82% A4% E3% 83% B3% E3% 83% 88), "Schrittausführung" /word15249.html), "[Stapelrahmen](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) "Überprüfen, ändern Sie den Wert der Variablen dynamisch usw. pdb bietet häufig verwendete Debug-Operationsbefehle.

Befehl 短縮Befehl Erläuterung
break b Haltepunkte setzen;b <Anzahl der Zeilen>で指定Anzahl der Zeilenにブレークポイントを設置できる
continue cont/c Setzen Sie die Ausführung bis zum nächsten Haltepunkt fort
next n Führen Sie die nächste Zeile aus, die nächste Zeile geht nicht hinein, wenn es sich um ein Unterprogramm (Funktion usw.) handelt.
step s Führen Sie die nächste Zeile aus, die nächste Zeile wird angezeigt, wenn es sich um ein Unterprogramm (Funktion usw.) handelt.
where bt/w "Stapelspur"Show
enable - Aktivieren Sie deaktivierte Haltepunkte
disable - Deaktivieren Sie aktivierte Haltepunkte
pp/p - p <Variablennamen>Drucken Sie Variablen mit
list l Anzeigen von Quellen in der aktuellen Zeile (mit dem Befehl ll können Sie einen größeren Bereich von Quellen anzeigen)
up u Gehen Sie zum Stapelrahmen oben
down d Gehen Sie zum Stapelrahmen unten
restart run Starten Sie das Debuggen neu
args a Funktionsargumente drucken
clear cl Entfernen Sie alle Haltepunkte.cl <Nummer>で指定Nummerのブレークポイントを削除できる
return r Führen Sie bis zum Ende der Funktion aus
help h h <Befehlsname>Befehlshilfe anzeigen mit
quit q Beenden Sie das Debuggen

Sie können den "pdb" -Debugger auf zwei Arten starten. Eine besteht darin, das pdb-Modul mit einem Befehlszeilenargument anzugeben und die Python-Datei zu starten.

python -m pdb test_pdp.py

Die andere Möglichkeit besteht darin, Haltepunkte im pdb -Modul set_trace in Ihrem Python-Code zu setzen. Wenn das Programm zum Haltepunkt ausgeführt wird, wird der pdb-Debugger automatisch angehalten und gestartet.

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)

Es gibt keinen besonderen Unterschied zwischen den beiden Methoden, aber die Wahl ist von Fall zu Fall. Wenn Ihr Code kurz ist, ist es in Ordnung, pdb mit der Befehlszeilenargumentmethode zu starten. Auf der anderen Seite ist es bei großen Programmen einfacher, Haltepunkte im Voraus mit set_trace festzulegen, wo Sie debuggen möchten.

Sobald der "pdb" -Debugger gestartet ist, können Sie mit dem obigen Befehl debuggen. Das folgende Beispiel ist ein Debugging der Funktion der rekursiven Hierarchie. Zuerst habe ich den Aufrufstapel der Funktion mit bt überprüft und den Python-Code mit list betrachtet. Als nächstes druckte ich den Wert von "sum" mit "p" und folgte der rekursiven "return" mit "r". Und schließlich habe ich das Debuggen mit q beendet.

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):
...

Wenn sich die Ausgabe von "pdb" etwas schlicht anfühlt, gibt es auch ein Paket namens "ipdb", das die Ausgabe bereinigt. Es ist dasselbe Image wie "ipython", das die REPL-Umgebung bereinigt. Die API ist dieselbe, Sie können sie also so verwenden, wie sie ist, indem Sie "pdb importieren" in "ipdb als pdb importieren" ändern.

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

Es ist tatsächlich bunt und schöner.

Zusätzlich zu "ipub" gibt es auch ein Paket, das mit einem Browser namens "web-pdb" debuggt werden kann. Und die API ist die gleiche wie "pdb". Als Bild können Sie es anhand der folgenden Abbildung sehen.

Wenn Sie vim mögen, lesen Sie auch "PuDB" im CUI-Debugger. Das Bild ist in der folgenden Abbildung dargestellt. Es ist unwiderstehlich für CUI-Liebhaber. In Bezug auf die Verwendung empfehlen wir den [Artikel] von @ Kernel_OGSun (https://qiita.com/Kernel_OGSun/items/144c8502ce2eaa5e4410).

Debuggen mit Haltepunkt

In Python 3.7 (PEP 553) wurde eine integrierte Funktion namens "Haltepunkt" hinzugefügt. Die grundlegende Verwendung ist wie folgt.

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)

Standardmäßig ist es genau das gleiche wie "import pdb; pdb.set_trace ()".

Als erweiterte Verwendung können Sie verschiedene Funktionen hinzufügen, indem Sie eine Umgebungsvariable namens "PYTHONBREAKPOINT" festlegen. Sie können beispielsweise das Debuggen mit "PYTHONBREAKPOINT = 0" deaktivieren, sodass Sie nicht mehr jeden "breakpoint ()" in Ihrem Code löschen müssen.

Wenn Sie dann "PYTHONBREAKPOINT =" importable.callable "setzen, wird" importable.callable "als" import "und" callable "aufgerufen. Beispielsweise können Sie "web-pdb" wie folgt verwenden:

PYTHONBREAKPOINT='web_pdb.set_trace' python test_pdb.py

Dies ist sehr praktisch, da Sie den Debugger ersetzen können, ohne eine einzelne Zeile Python-Code zu ändern, indem Sie nur die Umgebungsvariablen ändern.

Debuggen mit Visual Studio Code

Das Debuggen mit VSCode ist sehr einfach.

Klicken Sie zunächst auf das Fehlersymbol in der linken Symbolleiste. Zum ersten Mal müssen Sie launch.json erstellen, aber die Standardeinstellungen sind ziemlich gut.                                                                                                        Screen Shot 2020-09-30 at 23.25.01.png

Sie können dann einen Haltepunkt festlegen, indem Sie neben der Zeilennummer klicken.                                                                             Screen Shot 2020-09-30 at 23.34.09.png

Klicken Sie dann auf Debug starten, um es auszuführen.                                                                             Screen Shot 2020-09-30 at 23.39.44.png

Dann wird der nächste Bildschirm angezeigt. Screen Shot 2020-09-30 at 23.42.46.png

Sie können das Debuggen über die Schaltfläche oben rechts ausführen.                                                       Screen Shot 2020-09-30 at 23.57.30.png

"Step Over" ist eine Funktion, die "next" von "pdb" entspricht. Außerdem ist "Step In" der "Schritt" von "pdb" und "Step Out" "Return". Die GUI ist einfach zu bedienen.

Debuggen mit PyCharm

Grundsätzlich ist es die gleiche Schnittstelle wie VS Code. Screen Shot 2020-10-01 at 0.05.49.png

Beginnen Sie mit dem Debuggen mit dem Fehlersymbol oben rechts und enden Sie mit dem quadratischen Symbol.                                                                             Screen Shot 2020-10-01 at 0.07.25.png

Wenn Sie das Debug ausführen möchten, können Sie hauptsächlich diese Schaltfläche verwenden.                                                                             Screen Shot 2020-10-01 at 0.10.34.png

Drücken Sie den Futako-Ball links, um den Bildschirm unten aufzurufen. Es ist sehr praktisch, die Bedingungen für die Eingabe des Haltepunkts mit "Bedingung" festlegen zu können. Screen Shot 2020-10-01 at 0.14.37.png

Drücken Sie auf das Rechnersymbol ganz rechts, um den folgenden Bildschirm aufzurufen. Sie können Variablen usw. überprüfen. Screen Shot 2020-10-01 at 0.16.31.png

Zusammenfassung

Ich habe viel über Python-Debugging gesehen. Erstens die Standardbibliothek "pdb" und ihre Derivate. Lassen Sie uns als Python-Entwickler "pdb" vorerst zurückhalten. Ich habe mir auch VS Code und PyCharms GUI-Debugger angesehen. Es ist im Grunde sehr einfach zu bedienen. Wenn Sie also "pdb" kennen, können Sie es sofort verwenden. Natürlich hat die fortgeschrittene Nutzung keine andere Wahl, als Erfahrungen in der Praxis zu sammeln.

Recommended Posts

Vollständiges Verständnis des Python-Debuggens
Vollständiges Verständnis von Python-Threading und Multiprocessing
Asynchrone Verarbeitung von Python ~ Asynchron vollständig verstehen und warten ~
[Python] Die potenzielle Feldplanung von Python Robotics verstehen
Python DS-Debugging
Python-Handspiel (berechnet voller Mordred)
Tipps zum Python-Debuggen
Grundlagen von Python ①
Kopie von Python
Python selbst verstehen
Einführung von Python
Vollständiges Verständnis der Konzepte von Bellmanford und Dyxtra
Einfaches Verständnis von Python für & Arrays (für Super-Anfänger)
[Python] Ein grobes Verständnis des Protokollierungsmoduls
[Python] Ein grobes Verständnis von Iterablen, Iteratoren und Generatoren
[Python] Operation der Aufzählung
Liste der Python-Module
Vereinheitlichung der Python-Umgebung
Kopie der Python-Einstellungen
[Python] Super nützliches Debugging
Grundlagen der Python-Scraping-Grundlagen
[Python] Verhalten von Argmax
Verwendung von Python-Einheimischen ()
der Zen von Python
Installieren von Python 3.3 rc1
elasticsearch_dsl Memorandum
Python Bit vollständige Suche
# 4 [Python] Grundlagen der Funktionen
Grundkenntnisse in Python
Nüchterne Trivia von Python3
Zusammenfassung der Python-Argumente
Grundlagen von Python: Ausgabe
Installation von matplotlib (Python 3.3.2)
Anwendung von Python 3 vars
Verschiedene Verarbeitung von Python
Erhalten Sie ein abstraktes Verständnis der Python-Module und -Pakete
[Python] Richtige Verwendung der Karte
[Python] Effizienteres Debuggen!
Zusammenfassung der Python-Dateivorgänge
Zusammenfassung der Python3-Listenoperationen
Python - Schneller Start der Protokollierung
Empfehlung der binpacking Bibliothek von Python
[Python] Wert des Funktionsobjekts (?)
Automatisches Update des Python-Moduls
Python --Überprüfen Sie den Wertetyp
Vollständiges Verständnis der Funktion numpy.pad
[Python] Der Ursprung des Namens der Python-Funktion
Über verschiedene Codierungen von Python 3
Objektäquivalenzbeurteilung in Python
Einführung in Aktivitäten mit Python
Installieren Sie mehrere Versionen von Python
Upgrade von Python Anaconda
Umgang mit Python auf Mac
Python: Grundlagen der Verwendung von Scikit-Learn ①
Vollbit-Suche mit Python
2.x, 3.x Serienzeichencode von Python
Paiza Python Primer 8: Grundlegendes zu Klassen
Vergleich von 4 Arten von Python-Webframeworks