Как выполнить многострочные операторы в собственном отладчике Python (PDB)

157

Итак, я запускаю скрипт Python, внутри которого я вызываю отладчик Python, PDB:

import ipdb; ipdb.set_trace()

(Версия PDB от iPython, хотя я не думаю, что это имеет значение; я использую ее только для цветного вывода).

Теперь, когда я попадаю в отладчик, я хочу выполнить многострочный оператор, такой как условие if или цикл for, но как только я наберу

if condition:

и нажмите клавишу возврата, я получаю сообщение об ошибке *** SyntaxError: invalid syntax (<stdin>, line 1)

Как выполнить многострочные операторы в PDB? Если это невозможно, есть ли способ избежать выполнения предложения if или цикла for?

Майк
источник

Ответы:

265

Вы можете сделать это, находясь в pdb, чтобы запустить временный интерактивный сеанс Python со всеми доступными локальными переменными:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Когда вы закончите, используйте Ctrl-D, чтобы вернуться к обычному приглашению pdb.

Только не нажимайте Ctrl-C, это завершит весь сеанс pdb.

Мариус Гедминас
источник
46
Кажется, того же можно добиться с помощью команды pdb interact( как я узнал из этого сообщения об ошибке ).
геррит
3
Зачем !нужно в importзаявлении?
Индрадхануш Гупта
19
Это, вероятно, не нужно, но у меня есть привычка ставить префиксы перед всеми операторами Python в pdb !, чтобы избежать несчастных случаев. Например, c = 42в pdb будет продолжаться выполнение вместо присвоения переменной c.
Мариус Гедминас
8
@MariusGedminas самая неприятная вещь с PDB! Было бы хорошо, если бы их команды должны были иметь префикс ...
Ян Кларк
Примечание: Ctrl-D, похоже, interactтоже правильный путь для выхода , но он не очень подходит для Spyder для меня.
Иосия Йодер
70

В python3 ipdbpdb) есть команда под названием взаимодействовать . Может использоваться для:

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

Чтобы использовать его, просто введите interactв приглашении pdb. Помимо прочего, это полезно для применения кода, занимающего несколько строк, а также для предотвращения случайного запуска других команд pdb.

vaer-к
источник
2
Это дает мне «NameError: имя« взаимодействовать »не определено» при этом.
Джейсон
1
@jason версия 3.2 или выше
vaer-k
2
Это объясняет Я был в Python 2.7.
Джейсон
Осторожно, это фактически
выдало
1
Я думаю, что предложение избегать interact- слишком сильное предложение. 90% - это все, что мне когда-либо нужно, и это гораздо легче набрать, чемfrom IPython import embed; embed()
vaer-k
43

Я рекомендую использовать встраивание IPython.

ipdb> from IPython import embed; embed()
FX-кирин
источник
2
Если у вас есть значение не определена ошибка в понимании списка, попробуйте использовать из IPython import embed; embed(user_ns=locals()).
FX-
1
это работает намного лучше для меня, чем принятый ответ. Например, он позволяет правильно редактировать многострочный текст - например, вернуться на несколько строк назад и исправить что-то, чтобы вам не приходилось переписывать все ваше многострочное выражение снова ... Я передаю локальные данные как @ fx-kirin предложил.
ZeDuS
33

Внутри интерпретатора или отладчика Python (2.7.1) (import pdb) вы можете выполнить многострочный оператор со следующим синтаксисом.

for i in range(5): print("Hello"); print("World"); print(i)

Примечание: когда я нахожусь внутри интерпретатора, мне нужно дважды нажать return, прежде чем код будет выполнен. Внутри отладчика, однако, мне нужно нажать «возврат» только один раз.

Гаррет Хайд
источник
5
Он не позволяет запускать что-то более глубокое, чем один уровень.
Энтони Хэтчкинс
7

Существует особый случай, если вы хотите, чтобы пара команд выполнялась при достижении точки останова. Тогда есть команда отладчика commands. Это позволяет вводить несколько строк команд, а затем завершать всю последовательность endключевым словом. Больше с (pdb) help commands.

ThomasH
источник
2

Я не знаю, сможете ли вы сделать это, но это была бы отличная возможность для ipdb. Конечно, вы можете использовать списочные выражения и выполнять простые многострочные выражения, такие как:

if y == 3: print y; print y; print y;

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

zeekay
источник