(Оновлення 28 травня 2016 р.) Використання RealGUD в Emacs
Для всіх, хто в Emacs, цей потік показує, як виконати все, що описано в ОП (і більше), використовуючи
- новий важливий налагоджувач у Emacs під назвою RealGUD, який може працювати з будь-яким налагоджувачем (у тому числі
ipdb
).
- Пакет Emacs
isend-mode
.
Поєднання цих двох пакетів надзвичайно потужне і дозволяє відтворити саме поведінку, описану в ОП, і зробити ще більше.
Більше інформації про статтю вікі RealGUD для ipdb.
Оригінальна відповідь:
Спробувавши багато різних методів налагодження Python, включаючи все, що згадується в цій темі, один із моїх бажаних способів налагодження Python за допомогою IPython - це вбудовані оболонки.
Визначення спеціальної вбудованої оболонки IPython:
Додайте до скрипту наступне PYTHONPATH
, щоб метод ipsh()
став доступним.
import inspect
# First import the embed function
from IPython.terminal.embed import InteractiveShellEmbed
from IPython.config.loader import Config
# Configure the prompt so that I know I am in a nested (embedded) shell
cfg = Config()
prompt_config = cfg.PromptManager
prompt_config.in_template = 'N.In <\\#>: '
prompt_config.in2_template = ' .\\D.: '
prompt_config.out_template = 'N.Out<\\#>: '
# Messages displayed when I drop into and exit the shell.
banner_msg = ("\n**Nested Interpreter:\n"
"Hit Ctrl-D to exit interpreter and continue program.\n"
"Note that if you use %kill_embedded, you can fully deactivate\n"
"This embedded instance so it will never turn on again")
exit_msg = '**Leaving Nested interpreter'
# Wrap it in a function that gives me more context:
def ipsh():
ipshell = InteractiveShellEmbed(config=cfg, banner1=banner_msg, exit_msg=exit_msg)
frame = inspect.currentframe().f_back
msg = 'Stopped at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)
# Go back one level!
# This is needed because the call to ipshell is inside the function ipsh()
ipshell(msg,stack_depth=2)
Потім, коли я хочу налагодити щось у своєму коді, я розміщую його ipsh()
прямо в тому місці, де мені потрібно здійснити перевірку об’єктів тощо. Наприклад, скажіть, що я хочу налагоджуватиmy_function
нижче
Використовуючи його:
def my_function(b):
a = b
ipsh() # <- This will embed a full-fledged IPython interpreter
a = 4
а потім я закликаю my_function(2)
одним із наступних способів:
- Або запустивши програму Python, яка викликає цю функцію з оболонки Unix
- Або викликуючи його безпосередньо з IPython
Незалежно від того, як я викликаю це, перекладач зупиняється на рядку, який говорить ipsh()
. Як тільки ви закінчите, ви можете зробити це, Ctrl-D
і Python відновить виконання (з будь-якими змінними оновленнями, які ви зробили). Зауважте, що якщо ви запускаєте код із звичайного IPython оболонки IPython (випадок 2 вище), нова оболонка IPython буде вкладена всередині тієї, з якої ви її викликали, що цілком чудово, але це добре знати. Так чи інакше, коли перекладач зупиняється на розташуванні ipsh
, я можу перевірити значення a
(яке буде 2
), побачити, які функції та об'єкти визначені тощо.
Проблема:
Наведене вище рішення може бути використане для того, щоб Python зупинився в будь-якому місці вашого коду, а потім перейшов до повноцінного інтерпретатора IPython. На жаль, вона не дозволяє вам додавати або видаляти точки точки перелому після запуску сценарію, що дуже засмучує. На мою думку, це єдине , що не дозволяє IPython стати чудовим інструментом налагодження для Python.
Найкраще, що ви можете зробити зараз:
Вирішення проблеми полягає в тому, щоб ipsh()
апріорі розмістити в різних місцях, де ви хочете, щоб інтерпретатор Python запустив оболонку IPython (тобто a breakpoint
). Потім ви можете "перестрибувати" між різними заздалегідь визначеними жорстко кодованими "точками розриву" за допомогою Ctrl-D
, які вийшли б із поточної вбудованої оболонки IPython і знову зупиняються, коли інтерпретатор потрапляє на наступний дзвінок ipsh()
.
Якщо ви йдете цим маршрутом, одним із способів виходу з «режиму налагодження» та ігнорування всіх наступних точок прориву є використання, ipshell.dummy_mode = True
яке змусить Python ігнорувати будь-які наступні моменти ipshell
об’єкта, який ми створили вище.
!
команду, яка виконує будь-яку команду python на точці зламу