Как встроить интерпретатор IPython в приложение, работающее в консоли IPython Qt

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

У меня есть приложение python, работающее в консоли IPython qt.

http://ipython.org/ipython-doc/dev/interactive/qtconsole.html

Когда я сталкиваюсь с ошибкой, я хотел бы иметь возможность взаимодействовать с кодом в этот момент.

    try: 
      raise Exception()
    except Exception as e:
        try: # use exception trick to pick up the current frame
            raise None
        except:
            frame = sys.exc_info()[2].tb_frame.f_back
        namespace = frame.f_globals.copy()
        namespace.update(frame.f_locals)
        import IPython
        IPython.embed_kernel(local_ns=namespace)  

Я бы подумал, что это сработает, но я получаю сообщение об ошибке:

RuntimeError: потоки могут быть запущены только один раз


person Erotemic    schedule 01.03.2013    source источник
comment
Для тех, кто сейчас задается этим вопросом, см.: stackoverflow.com/questions/4234612/. (Есть официально поддерживаемый способ сделать это от IPython.)   -  person Linuxios    schedule 24.06.2019


Ответы (2)


Я просто использую это:

from IPython import embed; embed()

работает лучше, чем что-либо еще для меня :)


Обновление:

В честь того, что этот ответ получил 50 голосов, вот обновления, которые я сделал для этого фрагмента за прошедшие шесть лет с момента его публикации.

Во-первых, теперь мне нравится импортировать и выполнять в одном операторе, так как я использую black для всего своего кода на Python. в наши дни, и он переформатирует исходный фрагмент таким образом, что это не имеет смысла в этом конкретном и необычном контексте. Так:

 __import__("IPython").embed()

Учитывая, что я часто использую это внутри цикла или потока, может быть полезно включить фрагмент, который позволяет завершить родительский процесс (частично для удобства, а частично, чтобы напомнить себе, как лучше всего это сделать). os._exit — лучший выбор, поэтому мой фрагмент включает это (та же логика с использованием одного оператора):

q = __import__("functools").partial(__import__("os")._exit, 0)

Затем я могу просто использовать q(), если/когда я хочу выйти из главного процесса.

Мой полный фрагмент (с # FIXME на случай, если я когда-нибудь забуду его удалить!) выглядит так:

q = __import__("functools").partial(__import__("os")._exit, 0)  # FIXME
__import__("IPython").embed()  # FIXME  
person simon    schedule 02.02.2014
comment
Мне нравится использовать это для изучения новых проектов. Я создал bit.ly URL j.mp/ipshell, который я могу включить в свой код. Он указывает на gist.github.com/RichardBronosky/570492. - person Bruno Bronosky; 21.11.2016

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

person Amelio Vazquez-Reina    schedule 27.03.2013