Czy można przejść do ipython z kodu?

81

Dla moich potrzeb debugowania pdbjest całkiem niezły. Byłoby jednak dużo fajniejsze (i pomocne), gdybym mógł wejść do ipython. Czy to możliwe?

Geo
źródło

Odpowiedzi:

112

Istnieje ipdbprojekt, który osadza iPython w standardowym pdb, więc możesz po prostu zrobić:

import ipdb; ipdb.set_trace()

Można go zainstalować za pomocą zwykłego pip install ipdb.

ipdbjest dość krótki, więc zamiast easy_installing możesz również utworzyć plik ipdb.pygdzieś na swojej ścieżce Pythona i wkleić do niego następujące elementy:

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
źródło
Działa zadziwiająco dobrze z Django. Cóż, z wyjątkiem faktu, że nie widzę tekstu, który piszę, ale prawdopodobnie łatwo to naprawić (ponieważ ipdb ma tylko sześć linii).
Xiong Chiamiov
4
Właściwie problem polega na tym, że Django tworzy oddzielny wątek dla serwera uruchomieniowego i za każdym razem, gdy edytujesz kod, odradza wątek. Zwykle działa to dobrze, ale jeśli siedzisz w pdb, gdy wątek zostanie zabity, terminal oszaleje. Możesz to naprawić, wyrywając się z serwera runniny, „stty sane”, a następnie ponownie uruchamiając runnerver.
Jeremy Dunck
1
@ daniel-Roseman Cześć, mam ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'iImportError: cannot import name 'ipapi'
SebMa
1
@memoselyk Cześć, mam ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'iImportError: cannot import name 'ipapi'
SebMa
Jest sposób, aby dostać breakpoint()się do ipdb.
gerrit
53

W IPython 0.11 możesz osadzić IPython bezpośrednio w swoim kodzie w ten sposób

Twój program może wyglądać tak

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

Tak się dzieje, gdy go uruchamiasz (arbitralnie wybrałem uruchomienie go w ramach istniejącej sesji ipython. Z mojego doświadczenia wynika, że ​​zagnieżdżanie sesji ipython w ten sposób może spowodować jego awarię).

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
źródło
To wejście do sesji IPythona jest bardzo fajne. Dziękuję bardzo!
joon
1
Głupio umieściłem to w (prawie nieskończonej) pętli. Jak mogę się kiedykolwiek wydostać?
gerrit
2
@gerrit, naciśnij Ctrl + d, jeśli nadal tam jesteś.
zdezorientowany 00
2
@ confused00 To byłoby potężnie nieskończone 6 miesięcy później ;-)
gerrit
1
@gerrit, jeśli utkniesz w pętli osadzania: def f() : pass ; IPython.embed = ftak, aby embed()wywołanie było noop, a następnie Ctrl + D
MatrixManAtYrService,
12

Jeśli używasz nowocześniejszej wersji IPythona (> 0.10.2), możesz użyć czegoś takiego jak

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

Ale prawdopodobnie lepiej jest po prostu użyć ipdb

chrisdev
źródło
11

Odpowiednik

import pdb; pdb.set_trace()

z IPythonem wygląda mniej więcej tak:

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

Jest to trochę rozwlekłe, ale dobrze jest wiedzieć, jeśli nie masz zainstalowanego ipdb. make_sessionWezwanie jest wymagane raz skonfigurować schemat kolorów, itp, a set_tracepołączenia mogą być umieszczone w dowolnym miejscu trzeba złamać.

ars
źródło
8

Zwykle, kiedy używam ipythona, włączam automatyczne debugowanie za pomocą polecenia „pdb” w nim.

Następnie uruchamiam skrypt za pomocą polecenia „uruchom myscript.py” w katalogu, w którym znajduje się mój skrypt.

Jeśli otrzymam wyjątek, ipython zatrzymuje program wewnątrz debugera. Sprawdź polecenie pomocy dla magicznych poleceń ipython (% magic)

Jay Atkinson
źródło
więc nie ma możliwości napisania czegoś takiego jak ipython.set_trace ()? :)
Geo
8

Lubię po prostu wkleić ten jeden wiersz w moich skryptach, w których chcę ustawić punkt przerwania:

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

Nowsza wersja może używać:

__import__('IPython').core.debugger.Pdb(color_scheme='Linux').set_trace()
xApple
źródło
6

Wygląda na to, że moduły zostały ostatnio trochę przetasowane. Na IPythonie 0.13.1 działają dla mnie następujące rzeczy

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

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

Chociaż, niestety, w qtconsole to wszystko jest bezwartościowe .

beardc
źródło
5

Nowsze wersje IPythona zapewniają łatwy mechanizm osadzania i zagnieżdżania sesji IPython w dowolnych programach w języku Python. Możesz postępować zgodnie z następującym przepisem, aby osadzić sesje IPython:

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)

Następnie użyj, ipshell()gdy chcesz wejść do powłoki IPython. Umożliwi to osadzenie (a nawet zagnieżdżenie) interpreterów IPython w kodzie.

Amelio Vazquez-Reina
źródło
3

Z dokumentacji IPython :

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

uruchomi programowo powłokę IPythona. Oczywiście wartości w namespacedyktandzie są tylko wartościami fikcyjnymi - locals()w praktyce może być bardziej sensowne .

Zauważ, że musisz to na stałe zakodować w; to nie zadziała tak, jak pdbdziała. Jeśli tego chcesz, odpowiedź DoxaLogos jest prawdopodobnie bardziej podobna do tego, czego szukasz.

David Z
źródło
3

Szybki i łatwy sposób:

from IPython.Debugger import Tracer
debug = Tracer()

Następnie po prostu napisz

debug()

gdziekolwiek chcesz rozpocząć debugowanie programu.

Viktiglemma
źródło
1
ImportError: No module named 'IPython.Debugger'na pythonie 3.4 / IPython 3
ostrokach
2

Musiałem to wygooglować kilka razy w ciągu ostatnich kilku dni, więc dodając odpowiedź ... czasami fajnie jest móc normalnie uruchomić skrypt i wpadać do ipython / ipdb tylko w przypadku błędów, bez konieczności wstawiania ipdb.set_trace()punktów przerwania do kodu

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

(pierwszy pip install ipythoni pip install ipdboczywiście)

Anentropowy
źródło
1
Dziękuję Ci! Nieco prostsze:ipython --pdb -- ./path/to/my/script --with-args here
alisianoi
0

To jest całkiem proste:

ipython some_script.py --pdb

Wymaga instalacji iPythona, zwykle działa to: pip install ipython

Używam ipython3 zamiast ipython, więc wiem, że to najnowsza wersja Pythona.

Jest to łatwe do zapamiętania, ponieważ po prostu używasz iPythona zamiast pythona i dodajesz --pdb na końcu.

Luke Stanley
źródło