Ist es möglich, aus Code in Ipython zu wechseln?

81

Für meine Debugging-Bedürfnisse pdbist das ziemlich gut. Es wäre jedoch viel cooler (und hilfreicher), wenn ich darauf eingehen könnte ipython. Ist das möglich?

Geo
quelle

Antworten:

112

Es gibt ein ipdbProjekt, das iPython in die Standard-PDF-Datei einbettet. Sie können also einfach Folgendes tun:

import ipdb; ipdb.set_trace()

Es kann über das Übliche installiert werden pip install ipdb.

ipdbist ziemlich kurz, sodass Sie anstelle von easy_installing auch ipdb.pyirgendwo auf Ihrem Python-Pfad eine Datei erstellen und Folgendes in die Datei einfügen können:

import sys
from IPython.Debugger import Pdb
from IPython.Shell import IPShell
from IPython import ipapi

shell = IPShell(argv=[''])

def set_trace():
    ip = ipapi.get()
    def_colors = ip.options.colors
    Pdb(def_colors).set_trace(sys._getframe().f_back)
Daniel Roseman
quelle
Funktioniert erstaunlich gut mit Django. Nun, außer der Tatsache, dass ich den Text, den ich schreibe, nicht sehen kann, aber das ist wahrscheinlich leicht zu beheben (da ipdb nur sechs Zeilen hat).
Xiong Chiamiov
4
Tatsächlich besteht das Problem darin, dass Django einen separaten Thread für den Runserver gibt und jedes Mal, wenn Sie einen Code bearbeiten, der Thread erneut angezeigt wird. Dies funktioniert normalerweise einwandfrei, aber wenn Sie in pdb sitzen, wenn der Thread beendet wird, wird das Terminal verrückt. Sie können dies beheben, indem Sie aus dem Runserver ausbrechen, "stty sane" ausführen und dann den Runserver erneut starten.
Jeremy Dunck
1
@ Daniel-Roseman Hallo, ich verstehe ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'undImportError: cannot import name 'ipapi'
SebMa
1
@memoselyk Hallo, ich verstehe ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'undImportError: cannot import name 'ipapi'
SebMa
Es gibt eine Möglichkeit, die breakpoint()Funktion auf ipdb zu übertragen.
Gerrit
53

In IPython 0.11 können Sie IPython wie folgt direkt in Ihren Code einbetten

Ihr Programm könnte so aussehen

In [5]: cat > tmpf.py
a = 1

from IPython import embed
embed() # drop into an IPython session.
        # Any variables you define or modify here
        # will not affect program execution

c = 2

^D

Dies passiert, wenn Sie es ausführen (ich habe es willkürlich ausgewählt, es in einer vorhandenen Ipython-Sitzung auszuführen. Das Verschachteln von Ipython-Sitzungen wie dieser kann meiner Erfahrung nach zum Absturz führen).

In [6]:

In [6]: run tmpf.py
Python 2.7.2 (default, Aug 25 2011, 00:06:33)
Type "copyright", "credits" or "license" for more information.

IPython 0.11 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: who
a       embed

In [2]: a
Out[2]: 1

In [3]:
Do you really want to exit ([y]/n)? y


In [7]: who
a       c       embed
Alex Gaudio
quelle
Das Ablegen in eine IPython-Sitzung ist sehr cool. Ich danke dir sehr!
Joon
1
Ich habe das törichterweise in eine (fast unendliche) Schleife gelegt. Wie kann ich jemals raus?
Gerrit
2
@gerrit, drücke Strg + d, wenn du noch da bist.
verwirrt00
2
@ verwirrte00 Das wäre 6 Monate später mächtig unendlich gewesen ;-)
gerrit
1
@gerrit, Wenn Sie in einer Einbettungsschleife stecken: def f() : pass ; IPython.embed = fso dass der embed()Anruf ein Noop ist, dann Strg + D
MatrixManAtYrService
12

Wenn Sie eine modernere Version von IPython (> 0.10.2) verwenden, können Sie so etwas wie verwenden

from IPython.core.debugger import Pdb
Pdb().set_trace()

Aber es ist wahrscheinlich besser, nur ipdb zu verwenden

chrisdev
quelle
11

Das Äquivalent von

import pdb; pdb.set_trace()

mit IPython ist so etwas wie:

from IPython.ipapi import make_session; make_session()
from IPython.Debugger import Pdb; Pdb().set_trace()

Es ist ein bisschen ausführlich, aber gut zu wissen, wenn Sie keine ipdb installiert haben. Der make_sessionAnruf ist einmal erforderlich, um das Farbschema usw. einzurichten, und set_traceAnrufe können überall dort getätigt werden, wo Sie eine Unterbrechung benötigen.

ars
quelle
8

Wenn ich ipython verwende, aktiviere ich normalerweise das automatische Debuggen mit dem darin enthaltenen Befehl "pdb".

Anschließend führe ich mein Skript mit dem Befehl "run myscript.py" in dem Verzeichnis aus, in dem sich mein Skript befindet.

Wenn ich eine Ausnahme erhalte, stoppt ipython das Programm im Debugger. Überprüfen Sie den Hilfebefehl für die magischen Ipython-Befehle (% magic).

Jay Atkinson
quelle
Es gibt also keine Möglichkeit, so etwas wie ipython.set_trace () zu schreiben. :)
Geo
8

Ich möchte diesen Einzeiler einfach in meine Skripte einfügen, wo ich einen Haltepunkt setzen möchte:

__import__('IPython').Debugger.Pdb(color_scheme='Linux').set_trace()

Neuere Version könnte verwenden:

__import__('IPython').core.debugger.Pdb(color_scheme='Linux').set_trace()
xApple
quelle
6

Es sieht so aus, als ob Module in letzter Zeit ein bisschen gemischt wurden. Unter IPython 0.13.1 funktioniert Folgendes für mich

from IPython.core.debugger import Tracer; breakpoint = Tracer()

breakpoint() # <= wherever you want to set the breakpoint

Leider ist in qtconsole alles ziemlich wertlos .

Bart
quelle
5

Neuere Versionen von IPython bieten einen einfachen Mechanismus zum Einbetten und Verschachteln von IPython-Sitzungen in beliebige Python-Programme. Sie können das folgende Rezept befolgen , um IPython-Sitzungen einzubetten:

try:
    get_ipython
except NameError:
    banner=exit_msg=''
else:
    banner = '*** Nested interpreter ***'
    exit_msg = '*** Back in main IPython ***'

# First import the embed function
from IPython.frontend.terminal.embed import InteractiveShellEmbed
# Now create the IPython shell instance. Put ipshell() anywhere in your code
# where you want it to open.
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)

Verwenden ipshell()Sie dann, wann immer Sie in eine IPython-Shell fallen möchten. Auf diese Weise können Sie IPython-Interpreter in Ihren Code einbetten (und sogar verschachteln).

Amelio Vazquez-Reina
quelle
3

Aus den IPython-Dokumenten :

import IPython.ipapi
namespace = dict(
    kissa = 15,
    koira = 16)
IPython.ipapi.launch_new_instance(namespace)

startet programmgesteuert eine IPython-Shell. Offensichtlich sind die Werte im namespaceDiktat nur Dummy-Werte - es könnte sinnvoller sein, sie zu verwendenlocals() in der Praxis zu verwenden.

Beachten Sie, dass Sie dies fest codieren müssen. es wird nicht so funktionieren wie pdbes ist. Wenn Sie das möchten, entspricht die Antwort von DoxaLogos wahrscheinlich eher Ihrer Suche.

David Z.
quelle
3

Der schnelle und einfache Weg:

from IPython.Debugger import Tracer
debug = Tracer()

Dann schreib einfach

debug()

Überall dort, wo Sie mit dem Debuggen Ihres Programms beginnen möchten.

Viktiglemma
quelle
1
ImportError: No module named 'IPython.Debugger'auf Python 3.4 / IPython 3
Ostrokach
2

Ich musste dies ein paar Mal googeln, wenn ich in den letzten Tagen eine Antwort hinzufügte ... manchmal ist es schön, ein Skript normal ausführen zu können und nur bei Fehlern in ipython / ipdb zu landen, ohne ipdb.set_trace()Haltepunkte in den Code einfügen zu müssen

ipython --pdb -c "%run path/to/my/script.py --with-args here"

(zuerst pip install ipythonund pip install ipdbnatürlich)

Anentropisch
quelle
1
Danke dir! Ein bisschen einfacher:ipython --pdb -- ./path/to/my/script --with-args here
Alisianoi
0

Das ist ziemlich einfach:

ipython some_script.py --pdb

Es muss iPython installiert werden. Normalerweise funktioniert dies: pip install ipython

Ich verwende ipython3 anstelle von ipython, daher weiß ich, dass es sich um eine neuere Version von Python handelt.

Dies ist einfach zu merken, da Sie nur iPython anstelle von Python verwenden und am Ende --pdb hinzufügen.

Luke Stanley
quelle