Ausführen mehrzeiliger Anweisungen in Pythons eigenem Debugger (PDB)

157

Ich führe also ein Python-Skript aus, in dem ich Pythons Debugger PDB aufrufe, indem ich Folgendes schreibe:

import ipdb; ipdb.set_trace()

(iPythons Version von PDB, obwohl ich nicht denke, dass es einen Unterschied macht; ich verwende sie nur für die farbige Ausgabe).

Wenn ich jetzt zum Debugger komme, möchte ich eine mehrzeilige Anweisung wie eine if-Klausel oder eine for-Schleife ausführen, aber sobald ich tippe

if condition:

und drücken Sie die Eingabetaste, ich erhalte die Fehlermeldung *** SyntaxError: invalid syntax (<stdin>, line 1)

Wie kann man mehrzeilige Anweisungen innerhalb von PDB ausführen? Wenn dies nicht möglich ist, gibt es eine Möglichkeit, eine if-Klausel oder eine for-Schleife weiterhin auszuführen?

Mike
quelle

Antworten:

265

Sie können dies in pdb tun, um eine temporäre interaktive Python-Sitzung mit allen verfügbaren lokalen Variablen zu starten:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Wenn Sie fertig sind, verwenden Sie Strg-D, um zur regulären PDF-Eingabeaufforderung zurückzukehren.

Drücken Sie einfach nicht Strg-C, um die gesamte PDF-Sitzung zu beenden.

Marius Gedminas
quelle
46
Es scheint, dass das gleiche mit dem interactBefehl pdb erreicht werden kann ( wie ich aus dieser Bug-Tracker-Nachricht gelernt habe ).
Gerrit
3
Warum wird das !in der importErklärung benötigt ?
Indradhanush Gupta
19
Es wird wahrscheinlich nicht benötigt, aber ich habe die Angewohnheit, allen Python-Anweisungen in pdb ein Präfix voranzustellen !, um Unfälle zu vermeiden. ZB c = 42in pdb würde die Ausführung fortgesetzt, anstatt der Variablen zuzuweisen c.
Marius Gedminas
8
@MariusGedminas das Frustrierendste mit PDB! Wäre schön, wenn ihre Befehle vorangestellt werden müssten ...
Ian Clark
Hinweis: Strg-D scheint auch der richtige Weg zum Beenden interactzu sein, aber es spielt für mich mit Spyder nicht gut.
Josiah Yoder
69

In Python3 ipdb(und pdb) haben Sie einen Befehl namens Interact . Es kann verwendet werden, um:

Starten Sie eine interaktive Interpreter (mit der Code - Modul) , deren globalen Namensraum enthält alle (global und lokal) Namen im aktuellen Bereich gefunden.

Um es zu verwenden, geben Sie einfach interactan der pdb-Eingabeaufforderung ein. Dies ist unter anderem nützlich, um Code über mehrere Zeilen anzuwenden und um ein versehentliches Auslösen anderer pdb-Befehle zu vermeiden.

vaer-k
quelle
2
Es gibt mir "NameError: Name 'Interaktion' ist nicht definiert", wenn ich das tue.
Jason
1
@ Jason Version 3.2 oder höher
Vaer-k
2
Das erklärt. Ich war in Python 2.7.
Jason
Vorsicht, dies warf tatsächlich einen Fehler, dass Interaktion nicht definiert werden konnte und beendete den Prozess
Camron_Godbout
1
Ich denke, zu vermeiden interactist ein zu starker Vorschlag. 90% das ist alles was ich jemals brauche und es ist viel einfacher zu tippen alsfrom IPython import embed; embed()
vaer-k
43

Meine Empfehlung ist die Verwendung der IPython-Einbettung.

ipdb> from IPython import embed; embed()
fx-kirin
quelle
2
Wenn Ihr Wert nicht als Fehler beim Listenverständnis definiert ist, versuchen Sie, ihn über IPython zu verwenden import embed; embed(user_ns=locals()).
FX-Kirin
1
Das funktioniert bei mir weitaus besser als die akzeptierte Antwort. Zum Beispiel - es ermöglicht die ordnungsgemäße Bearbeitung von mehrzeiligen Zeilen - wie das Zurückgehen einiger Zeilen und das Korrigieren von Änderungen, damit Sie nicht Ihren gesamten mehrzeiligen Ausdruck erneut schreiben müssen ... Ich übergebe die Einheimischen als @ fx-kirin empfohlen.
ZeDuS
33

Im Python (2.7.1) -Interpreter oder -Debugger (Import pdb) können Sie eine mehrzeilige Anweisung mit der folgenden Syntax ausführen.

for i in range(5): print("Hello"); print("World"); print(i)

Hinweis: Wenn ich mich im Interpreter befinde, muss ich zweimal die Eingabetaste drücken, bevor der Code ausgeführt wird. Im Debugger muss ich jedoch nur einmal die Eingabetaste drücken.

Garrett Hyde
quelle
5
Es erlaubt nicht, etwas tiefer als ein Level zu laufen.
Antony Hatchkins
7

Es gibt den Sonderfall, wenn beim Erreichen eines Haltepunkts mehrere Befehle ausgeführt werden sollen. Dann gibt es den Debugger-Befehl commands. Sie können mehrere Befehlszeilen eingeben und dann die gesamte Sequenz mit dem endSchlüsselwort beenden . Mehr mit (pdb) help commands.

ThomasH
quelle
2

Ich weiß nicht, ob Sie dies tun können, aber das wäre eine großartige Funktion für ipdb. Sie können natürlich Listenverständnisse verwenden und einfache mehrzeilige Ausdrücke ausführen wie:

if y == 3: print y; print y; print y;

Sie können auch einige Funktionen im Voraus schreiben, um das zu tun, was Sie normalerweise tun müssen und normalerweise mehrere Zeilen benötigen.

Zeekay
quelle
-6

Schreiben Sie Ihren Code in einen Texteditor und fügen Sie ihn in den Debugger ein:

if True:
    print('a')

Es ist eine dumme Lösung, aber auch schnell und schmutzig. Es funktioniert auf dem Linux-Terminal, aber ich bin nicht sicher, ob es auf der Windows-Konsole funktioniert.

bizi
quelle
3
Ehrlich gesagt würde ich nicht sagen, dass das Aufrufen eines externen Programms, das Schreiben, Kopieren und Einfügen schnell und einfach schmutzig ist: P
The Data Scientician
4
Dies funktionierte nicht für mich und thew*** SyntaxError: unexpected EOF while parsing
Yash Kant