Lassen Sie sich während der Ausführung der Funktion in den Python-Interpreter fallen

90

Ich habe ein Python-Modul mit einer Funktion:

def do_stuff(param1 = 'a'):
    if type(param1) == int:
        # enter python interpreter here
        do_something()
    else:
        do_something_else()

Gibt es eine Möglichkeit, in den Befehlszeileninterpreter zu gelangen, in dem ich den Kommentar habe? so dass, wenn ich folgendes in Python ausführen:

>>> import my_module
>>> do_stuff(1)

Ich erhalte meine nächste Eingabeaufforderung in dem Umfang und Kontext, in dem ich den Kommentar habe do_stuff().

aaronstacy
quelle
Mögliches Duplikat von Enter Interactive Mode In Python
Mad Physicist

Antworten:

60

Einfügen

import pdb; pdb.set_trace()

wird an diesem Punkt den Python-Debugger aufrufen

Siehe hier: http://docs.python.org/library/pdb.html

Prestomation
quelle
pdbist großartige Vanillepython; Wenn Sie Platz für das Einbringen eines externen Pakets haben, ipdbist dies großartig - dieselbe Funktionalität wie der Debugger, jedoch mit der Hervorhebung der Syntax, der Tab-Vervollständigung usw. von ipython
khstacking am
Update - ipdbwar veraltet, heutzutage benutze ich pdbpp( pdb++) , das ähnliche Funktionen hat und mit import pdb; pdb.set_trace()(dh es Patches, die importieren, so ist es ein Drop-In-Ersatz)
Driftcatcher
@hangtwenty: warum sagst du ipdbwar veraltet? Ich kann keine Neuigkeiten davon finden.
Nick Matteo
@ Kundor huh, du hast recht. Ich erinnere mich noch genau daran, irgendwo gelesen zu haben, dass die Autoren beschlossen hatten, das Projekt nicht mehr zu warten, und auf ein anderes Projekt verwiesen hatten, das stattdessen verwendet werden sollte. Vielleicht ist das ein bisschen passiert und dann wurde es wiederbelebt? Ich könnte falsch liegen! In jedem Fall, genoss ich ipdbvorher, aber habe es genossen , pdbppda
driftcatcher
141

Wenn Sie eine standardmäßige interaktive Eingabeaufforderung wünschen (anstelle des Debuggers, wie durch Prestomation angezeigt), können Sie Folgendes tun:

import code
code.interact(local=locals())

Siehe: das Codemodul .

Wenn Sie IPython installiert haben und stattdessen eine IPython-Shell möchten, können Sie dies für IPython> = 0.11 tun:

import IPython; IPython.embed()

oder für ältere Versionen:

from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
ipshell(local_ns=locals())
Matt Anderson
quelle
27
Für IPython> = 0.11 gibt es in IPython keine Modul-Shell mehr. Starten Sie sie daher stattdessen mit "IPython importieren; IPython.embed ()".
evandrix
Ist es möglich, nach der Eingabe code.interact()a la PDB fortzufahren c(ontinue)?
Nick T
4
code.interact()ist ein blockierender Anruf. Ihr Programm stoppt und wartet, bis es beendet ist. Wenn Sie den interaktiven Interpreter verlassen, sollte Ihr Programm mit der unmittelbar folgenden Anweisung fortgesetzt werden.
Matt Anderson
1
Was ist der Unterschied zwischen einer interaktiven Eingabeaufforderung und einem Debugger?
StockB
1
@StockB Es ist die standardmäßige interaktive Eingabeaufforderung, die es wichtig macht. Der Debugger ist eine interaktive Eingabeaufforderung, die jedoch nicht identisch ist. In PDB können Sie keine mehrzeiligen Anweisungen help
ausführen
28

Wenn Sie einen Standard-Python-Interpreter möchten, können Sie dies tun

import code
code.interact(local=dict(globals(), **locals()))

Dies ermöglicht den Zugang sowohl zu Einheimischen als auch zu Einheimischen.

Wenn Sie in einen IPython-Interpreter wechseln möchten, ist die IPShellEmbedLösung veraltet . Derzeit funktioniert Folgendes:

from IPython import embed
embed()
Ronan Paixão
quelle
8
danke, code.interact(local=dict(globals(), **locals()))ist so viel besser als code.interact(local=locals())weil letzteres dich dazu bringt, Pakete wieder zu importieren
s2t2
Diese Antwort funktionierte besser für mich, da ich ein Bash-Skript verwendete, um meinen Python-Code aufzurufen. Ich konnte mit der akzeptierten Antwort nicht mit meinem Python-Code interagieren. Vielen Dank!
Jonathanking