Можно ли зайти в ipython из кода?

81

Для моих нужд отладки pdbэто очень хорошо. Однако было бы намного круче (и полезно), если бы я мог углубиться в ipython. Возможно ли это?

Гео
источник

Ответы:

112

Существует ipdbпроект, который встраивает iPython в стандартный pdb, поэтому вы можете просто сделать:

import ipdb; ipdb.set_trace()

Устанавливается через обычный pip install ipdb.

ipdbдовольно короткий, поэтому вместо easy_installing вы также можете создать файл ipdb.pyгде-нибудь на своем пути Python и вставить в него следующее:

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)
Дэниел Розман
источник
Прекрасно работает с Django. Ну, за исключением того факта, что я не вижу набираемый текст, но это, вероятно, легко исправить (поскольку в ipdb всего шесть строк).
Xiong Chiamiov
4
На самом деле проблема в том, что Django создает отдельный поток для сервера выполнения, и каждый раз, когда вы вносите правку в код, он возрождает поток. Обычно это работает нормально, но если вы сидите в pdb, когда поток прерывается, терминал сходит с ума. Вы можете исправить это, выйдя из runserver, запустив 'stty sane', а затем снова запустив runserver.
Джереми Данк,
1
@ daniel-roseman Привет, я понял ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'иImportError: cannot import name 'ipapi'
SebMa
1
@memoselyk Привет, я понимаю ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'иImportError: cannot import name 'ipapi'
SebMa
Есть способ заставить breakpoint()функцию попасть в ipdb.
gerrit
53

В IPython 0.11 вы можете встроить IPython прямо в свой код следующим образом

Ваша программа может выглядеть так

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

Вот что происходит, когда вы запускаете его (я произвольно выбрал запускать его внутри существующего сеанса ipython. Вложенные сеансы ipython, подобные этому, по моему опыту, могут привести к его сбою).

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
Алекс Гаудио
источник
Переход в сеанс IPython - это очень круто. Спасибо огромное!
joon
1
Я по глупости поместил это в (почти бесконечный) цикл. Как мне выбраться отсюда?
gerrit
2
@gerrit, нажмите Ctrl + d, если вы все еще там.
confused00
2
@ confused00 Через 6 месяцев это было бы бесконечно ;-)
gerrit
1
@gerrit, если вы застряли в цикле встраивания: def f() : pass ; IPython.embed = fчтобы embed()вызов был беззвучным, тогда Ctrl + D
MatrixManAtYrService
12

Если вы используете более современную версию IPython (> 0.10.2), вы можете использовать что-то вроде

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

Но, наверное, лучше просто использовать ipdb

chrisdev
источник
11

Эквивалент

import pdb; pdb.set_trace()

с IPython выглядит примерно так:

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

Это немного многословно, но полезно знать, если у вас не установлен ipdb. make_sessionВызова требуется один раз настроить цветовую схему, и т.д., и set_traceзвонки могут быть размещены в любом месте вам нужно сломать.

арс
источник
8

Обычно, когда я использую ipython, я включаю автоматическую отладку с помощью команды «pdb» внутри него.

Затем я запускаю свой сценарий с помощью команды «запустить myscript.py» в каталоге, в котором находится мой сценарий.

Если я получаю исключение, ipython останавливает программу внутри отладчика. Ознакомьтесь с командой справки по волшебным командам ipython (% magic)

Джей Аткинсон
источник
так что нет возможности написать что-то вроде ipython.set_trace ()? :)
Geo
8

Мне нравится просто вставлять этот однострочник в свои сценарии, где я хочу установить точку останова:

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

Более новая версия может использовать:

__import__('IPython').core.debugger.Pdb(color_scheme='Linux').set_trace()
xApple
источник
6

Похоже, в последнее время модули немного перетасовывались. На IPython 0.13.1 для меня работает следующее

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

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

Хотя, увы, в qtconsole все это бесполезно .

бородаc
источник
5

Новые версии IPython предоставляют простой механизм для встраивания и вложения сеансов IPython в любые программы Python. Вы можете следовать следующему рецепту для внедрения сессий 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)

Затем используйте, ipshell()когда хотите перейти в оболочку IPython. Это позволит вам встраивать (и даже вкладывать) интерпретаторы IPython в ваш код.

Амелио Васкес-Рейна
источник
3

Из документов IPython :

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

программно запустит оболочку IPython. Очевидно, что значения в namespacedict - это просто фиктивные значения - это может иметь больше смысла для практического использования locals().

Обратите внимание, что вам нужно жестко запрограммировать это в; это не будет работать так, как pdbработает. Если это то, что вам нужно, ответ DoxaLogos, вероятно, больше похож на то, что вы ищете.

Дэвид З
источник
3

Быстрый и легкий способ:

from IPython.Debugger import Tracer
debug = Tracer()

Тогда просто напишите

debug()

везде, где вы хотите начать отладку своей программы.

Виктиглемма
источник
1
ImportError: No module named 'IPython.Debugger'на python 3.4 / IPython 3
острокач
2

Мне приходилось гуглить это пару раз в последние несколько дней, поэтому добавляю ответ ... иногда приятно иметь возможность нормально запускать скрипт и переходить в ipython / ipdb только при ошибках, без необходимости вставлять ipdb.set_trace()точки останова в код

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

(сначала pip install ipythonи pip install ipdbконечно)

Анэнтропический
источник
1
Спасибо! Немного проще:ipython --pdb -- ./path/to/my/script --with-args here
alisianoi
0

Это довольно просто:

ipython some_script.py --pdb

Требуется установка iPython, обычно это работает: pip install ipython

Я использую ipython3 вместо ipython, поэтому знаю, что это последняя версия Python.

Это легко запомнить, потому что вы просто используете iPython вместо python и добавляете --pdb в конец.

Люк Стэнли
источник