Wie kann ich mit Spyder in Python effizient debuggen?

74

Ich mag Python und ich mag Spyder, aber ich finde das Debuggen mit Spyder schrecklich!

  • Jedes Mal, wenn ich einen Haltepunkt setze, muss ich zwei Tasten drücken: zuerst die Debug- und dann die Weiter-Taste (sie pausiert automatisch in der ersten Zeile), was ärgerlich ist.
  • Anstatt die Standard-iPython-Konsole mit automatischer Vervollständigung usw. zu haben, habe ich außerdem eine miese ipdb >> -Konsole, die nur Müll ist.
  • Das Schlimmste ist, dass diese Konsole sehr häufig einfriert, selbst wenn ich Ausdrucke oder einfache Auswertungen schreibe, um herauszufinden, was der Fehler ist. Das ist viel schlimmer als Matlab.
  • Last but not least, wenn ich eine Funktion aus der ipdb >> -Konsole aufrufe und einen Haltepunkt darin setze, wird sie dort nicht aufhören. Es scheint, als müsste ich den Haltepunkt dort setzen, bevor ich mit dem Debuggen beginne (Strg + F5).

Haben Sie eine Lösung oder können Sie mir vielleicht sagen, wie Sie Python-Skripte und -Funktionen debuggen?

Ich verwende die Neuinstallation von Anaconda auf einem Windows 8.1 64-Bit.

Hanan Shteingart
quelle
Nicht relevant für komplexes Debugging, aber ich muss oft in der Mitte des Skripts anhalten, um bestimmte Variablen für die weitere Entwicklung in der Konsole zu verwenden. Normalerweise setze ich nur sys.exit()vorübergehend ein, aber es wäre bequemer, wenn ich eine Haltepunktoption hätte.
Docht

Antworten:

53

( Spyder-Entwickler hier ) Wir sind uns bewusst, dass das Debuggen in Spyder alles andere als ideal ist. Was wir derzeit anbieten, ist dem Standard-Python-Debugger sehr ähnlich, aber wir arbeiten daran, die Dinge in unserer nächsten Hauptversion zu verbessern, um etwas näher an das zu bringen, was jeder Wissenschaftler von einem Debugger erwarten würde (kurz gesagt, eine reguläre IPython-Konsole, die dies ermöglicht Sie überprüfen und zeichnen Variablen am aktuellen Haltepunkt.

Nun zu Ihren Punkten:

  1. Das ist wahr. Wir denken daran, dies zu verbessern, damit Spyder in den Debug-Modus wechselt und das Programm ausführt, bis der erste Haltepunkt erreicht ist, wenn der Benutzer die Schaltfläche Ausführen drückt und in der aktuellen Datei ein Haltepunkt vorhanden ist.

  2. ipdbist die IPython-Debugger-Konsole. Leider ist es aufgrund von Einschränkungen in der IPython-Architektur sehr begrenzt (keine Code-Vervollständigung und kein Durchsuchen des Verlaufs mit Pfeilen). Darüber hinaus ist es nicht möglich, beliebigen Python-Code in einer ipdboder einer normalen pdbKonsole auszuführen . Die Befehle, die Sie ausführen können ipdb, können Sie lesen, wenn Sie den darin enthaltenen helpBefehl auswerten .

  3. Das liegt daran, dass Sie, wie gesagt, keinen beliebigen Python-Code auswerten können.

  4. Sie müssen neue Haltepunkte in unseren Editor einfügen, damit sie mit unseren Python / IPython-Konsolen synchronisiert werden

Carlos Cordoba
quelle
13
Ich möchte auf ein weiteres Merkmal hinweisen, das ich für wichtig halte. Derzeit ist das Debuggen nur über "Debug-Datei" möglich, bei der eine Datei von Anfang bis Ende in einer separaten Sitzung ausgeführt wird, wobei alle Variablen vergessen werden, die ich möglicherweise in der Konsole definiert habe. Es wäre großartig, mit dem Debuggen einer bestimmten Funktion beginnen zu können, während Variablen übergeben werden, die bereits in meinem Arbeitsbereich definiert sind (deren Neuberechnung manchmal teuer ist)
Leo
1
@neuronet, das funktioniert bereits, aber nur, wenn Sie die Debug-Taste drücken (dh die blaue Wiedergabe- / Pause-Taste).
Carlos Cordoba
2
@neuronet, bitte öffnen Sie ein Problem, um besser zu verstehen, was in Ihrem Fall passiert.
Carlos Cordoba
2
@CarlosCordoba ok wird reichen, wird meine Zeit in Anspruch nehmen, um zu versuchen, nichts Dummes zu tun. :)
Eric
1
@CarlosCordoba Ich glaube, ich habe es irgendwie zum Laufen gebracht. Ich musste sicherstellen, dass die gesamte Datei fehlerfrei war, und die Wiedergabe- / Pause-Taste drücken (weil Dinge wie Strg-F12 nichts taten, bis ich mit Strg-F5 in den Debug- Modus wechselte). Jetzt, wo ich das sehe, kann ich das genauer untersuchen, aber auch das OP hier und Ihre Antwort viel besser einschätzen. Matlab ist einfach so gut darin , dass ich mich daran gewöhnen muss ... Eine klare Dokumentation würde auch hier sehr viel bewirken, insbesondere für die Wiederherstellung von Matlab-Benutzern, die erwarten, dass Spyder "wie Matlab" ist.
Eric
27

Debugging-Workflow

Sie müssen verstehen, dass Sie tatsächlich eine andere Integration des Python-Debuggers verwendenpdb und ipdb(welche verwendet pdbund auf welche über das Modul zugegriffen werden kann ipdb). Ich hoffe, dieses triviale Beispiel hilft Ihnen dabei, es besser zu nutzen.

Angenommen, Sie möchten diesen Code debuggen:

def Waiting_fun():                      #1 line number one
    for i in range(100):                #2
        pass                            #3
                                        #4 
def New_sum(lista, to_s = False):       #5
    result = 0                          #6
    print 1                             #7
    for i in lista:                     #8
        print "summed"                  #9   
        result +=i                      #10
    Waiting_fun()                       #11
    if to_s:                            #12
        result = str(result)
    return result
a = New_sum([1,4,5,7,8])
b = New_sum([1,4],1)
c = 456
d = New_sum([6,8,9],1)
final_result = a*b*c*d
Out: Type error

Schnelles erstes Debuggen mit iPython% debug

%debug

Das erste, was ich mache, ist, pdb von iPython mit dem Befehl magic aufzurufen. %debugSie können es mit als Standardmechanismus festlegen %pdb.

%debug
> /home/opdate/Desktop/test.py(23)<module>()
     19 a = New_sum([1,4,5,7,8])
     20 b = New_sum([1,4],1)
     21 c = 456
     22 d = New_sum([6,8,9],1)
---> 23 final_result = a*b*c*d

Sobald Sie zu Mittag essen pdb. Sie finden alle Befehle in den offiziellen Dokumenten oder können sie mit dem Befehl hanzeigen. In dieser Phase verwende ich nur folgende Befehle:

  • p : Gibt die von Ihnen angegebenen Variablen aus
  • pp : hübsche Drucke
  • args: Wenn Sie sich in einer Funktion befinden, werden die Argumente gedruckt
  • pp locals() : kann nützlich sein, um alle Variablen zu drucken, aber meistens ist es ein Chaos!
  • ! Verwenden Sie es, wenn Sie Konflikte mit den in aufgeführten Befehlen vermeiden möchten h
  • whatis Variablenname: Äquivalent zum Typ (Variablenname)
  • u : Verschieben Sie den aktuellen Frame im Stack-Trace um eine Ebene nach oben (in einen älteren Frame).
  • d : Verschieben Sie den aktuellen Frame im Stack-Trace um eine Ebene nach unten (in einen neueren Frame).
  • q : Wenn Sie fertig sind, können Sie q zum Beenden verwenden

In unserem Fall:

ipdb> pp a,b,c,d
(25, '5', 456, '23')

Oder ipdb> !a,b,c,d(kein Leerzeichen zwischen dem Ausrufezeichen und dem ersten Wert). Es ist klar, dass b und d Zeichenfolgen sind, falls wir Folgendes verwenden können:

ipdb> whatis b
<type 'str'>

Mit Haltepunkten tiefer gehen

In 70% der Fälle %debugweisen Sie auf die Lösung hin. Wenn Sie weitere Funktionen wie Haltepunkte benötigen, ist es Zeit, Spyder zu verwenden. In diesem Fall möchten wir verstehen, warum beine Zeichenfolge einen Haltepunkt daneben setzt (Doppelklick neben der Zeilennummer im Editorfenster). Ich finde es viel besser , die Standard-Python-Konsole anstelle der IPython-Konsole zum Debuggen zu verwenden. Wählen Sie daher die Konsole aus, bevor Sie mit dem Debuggen beginnen: Geben Sie hier die Bildbeschreibung ein

Öffnen Sie dann die variable explorerOption, wenn Variablen vorhanden sind. Ich benutze Ctrl+ F5, um das Debuggen zu starten. Sie können die Schaltflächen oben verwenden, aber ich bevorzuge die unten gezeigten Verknüpfungen:

Geben Sie hier die Bildbeschreibung ein

(Pdb) c # we go to the breakpoint 
(Pdb) s # we step into the function
(Pdb) args # we see what parameters are inserted
(Pdb) s # going step-by-step
(Pdb) ⏎ # series of Enters go line by line quicker
#Here I'll use  whatis command but in fact I just look to
# the type in variable explorer of spyder.
(Pdb) whatis result #check if result is still int
(Pdb) unt #or until -useful to exiting from loops see doc.
(Pdb) n # we  don't  enter to the Waiting_fun function
(Pdb) s # going step-by-step
(Pdb) whatis result #we find that there the int is converted
(Pdb) j 6 # for double checking we jump back to 6 were the result is assigned 
# We may be tempted to j(ump) to line 12 but doing so we would skip all the code
#for avoiding a series of `s`,`unt` and `n` we can use this solution:
(Pdb) tbreak 12 #set a new temporary breakpoint. Also `b` it's ok most of the time
(Pdb) c  # go to it 
(Pdb) j 6 # we jump to 6 the code we jump is NOT executed
(Pdb) whatis result# we find that if we jump 12-13 result is still int

Jetzt haben wir den Fehler gefunden. Wir können auch eine Lösung testen, indem wir den Schritt bis 12 wiederholen und einstellento_s = False

(Pdb) to_s = False #!to_s = False to be on the safe side

Es klappt. Eine wichtige Funktion bei der Verwendung der Standard-PDF in der Python-Konsole ist, dass Sie eine automatische Konkurrenz haben und den Variablen-Explorer verwenden können, anstatt whatisund zu verwenden pp:

Geben Sie hier die Bildbeschreibung ein

Mit dem Variablen-Explorer können Sie auch den Wert der Variablen ändern, wodurch die Dinge noch schneller werden.

Bedingte Haltepunkte

Eine andere cleverere Möglichkeit, den Fehler zu lokalisieren, ist die Verwendung des bedingten Haltepunkts ( Shift+ F12). Ein großer Vorteil von Spyder ist das Debuggen und Verwenden von Listen-Haltepunkten. Bedingte Haltepunkte werden aktiviert, wenn die Bedingung lautet. TrueIn unserem Fall möchten wir ermitteln, wo b zu einer Zeichenfolge wird. Die Bedingung lautet also : type(b) == str. Normalerweise platziere ich viele bedingte Haltepunkte und sehe, welche die Bedingung erfüllen. Verwenden Sie dazu nicht Shift+, F12sondern platzieren Sie normale Haltepunkte, indem Sie neben der Zeile doppelklicken, und gehen Sie zu Debug-> Haltepunkte auflisten. Kopieren Sie die Bedingung in der Tabelle und fügen Sie sie in jeden Haltepunkt ein, wie in der folgenden Abbildung gezeigt.

Geben Sie hier die Bildbeschreibung ein

Von hier aus sind folgende Befehle zu verwenden:

(Pdb) c  # go to the first
(Pdb) u # it helps to understand when it happened
(Pdb) d # come back to the breakpoint
GM
quelle
4

Der PDF-Debugger funktioniert gut mit normalem Python . In Spyder wechsle ich einfach zur Python-Konsole, wenn ich interaktiv debuggen möchte.

import pdb

def yourfunction():
    # Interesting stuff done here
    pdb.set_trace() 

Nettes Intro zum Debuggen mit pdb https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/

LtGlahn
quelle
1
Leider:NOTE: The Python console is going to be REMOVED in Spyder 3.2. Please start to migrate your work to the IPython console instead.
C8H10N4O2
1

So debugge ich in Spyder, um ein Einfrieren der IDE zu vermeiden. Ich mache das, wenn ich das Skript im Debugging-Modus ändere.

  1. Ich schließe die aktuelle IPython-Konsole (Debugging) [x]
  2. Öffnen Sie eine neue [Menüleiste-> Konsolen-> IPython-Konsole öffnen]
  3. Rufen Sie den Debug-Modus erneut auf [blaue Wiedergabepause-Taste].

Immer noch etwas nervig, hat aber den zusätzlichen Vorteil, dass die Variablenliste gelöscht (zurückgesetzt) ​​wird.

oogieoogieful
quelle
1

Bisher hat noch niemand etwas über diese beiden erwähnt:

Vor Python habe ich VBA verwendet. Obwohl es sich um eine relativ alte Sprache handelt, die nicht regelmäßig aktualisiert wird, war eine Sache, die ich an VBA liebte, die Debugging-Funktion. Die 2 Debugging-Funktionen, die VBA am nächsten kommen oder die auch als "visuelles Debugging" bezeichnet werden können, sind:

1-PyCharm-Debugger

Dieses 6-minütige Video zeigt den PyCharm-Debugger.

2-PixieDebugger - Der Visual Python-Debugger für Jupyter-Notebooks, den Sie schon immer wollten

Da viele Programmierer JupyterNotebook verwenden, ist dieser Debugger nützlich. PixieDebugger ist fast dasselbe wie der PyCharm-Debugger. Ich werde hier nicht ins Detail gehen.

Sie können jedoch auf diesen Link verweisen

mcagriardic
quelle
2
Die Frage bezieht sich auf Spyder und keiner der von Ihnen erwähnten Debugger kann in Spyder verwendet werden.
Carlos Cordoba
1
Das ist mir bewusst. Ich habe nur die verschiedenen Arten von visuellen Python-Debuggern hervorgehoben. Nicht unbedingt für Spyder.
Mcagriardic
0

Ein kleines Extra zu Punkt 3:

Es schien mir auch, dass die Debug-Konsole häufig eingefroren war, Drucke ausführte, auswertete usw., aber durch Drücken der Stopp-Taste (Debug beenden) wurde sie normalerweise wieder an den unteren Rand des Aufrufstapels zurückgeführt, und dann konnte ich wieder nach oben gehen ('u'). zu dem Frame, in dem ich debuggte. Einen Versuch wert. Dies könnte für eine spätere Version von Spyder (2.3.5.2) sein.

Paul
quelle
0

Sie können Debug-Tastenkombinationen wie folgt verwenden: Schritt über F10 Schritt in F11 unter Extras> Einstellungen> Tastaturkürzel

Mahyar
quelle