pdb — Отладчик Python
Исходный код: Lib/pdb.py
Модуль pdb определяет интерактивный отладчик исходного кода для программ Python. Он поддерживает установку (условных) точек останова и пошаговое выполнение по строкам исходного кода, инспекцию стековых фреймов, вывод исходного кода и вычисление произвольного Python-кода в контексте любого стекового фрейма. Он также поддерживает постмортальную отладку и может вызываться под управлением программы.
Отладчик расширяемый — он фактически определён как класс Pdb. В настоящее время это не документировано, но легко понять, прочитав исходный код. Интерфейс расширения использует модули bdb и cmd.
См. также
-
Modulefaulthandler -
Используется для явного вывода трассировок Python при ошибках, по истечении таймаута или при сигнале пользователя.
-
Moduletraceback -
Стандартный интерфейс для извлечения, форматирования и вывода стековых трассировок программ Python.
Типичное использование для перехода в отладчик состоит в вставке:
import pdb; pdb.set_trace()
Или:
breakpoint()
в место, где вы хотите перейти в отладчик, а затем запустить программу. Вы можете затем проходить по коду, следуя этому заявлению, и продолжить выполнение без отладчика, используя команду continue.
Изменено в версии 3.7: Встроенная функция breakpoint(), когда вызывается с параметрами по умолчанию, может использоваться вместо import pdb; pdb.set_trace().
def double(x):
breakpoint()
return x * 2
val = 3
print(f"{val} * 2 is {double(val)}")
Подсказка отладчика — (Pdb), что указывает на то, что вы находитесь в режиме отладки:
> ...(2)double() -> breakpoint() (Pdb) p x 3 (Pdb) continue 3 * 2 is 6
Изменено в версии 3.3: Автодополнение с помощью модуля readline доступно для команд и аргументов команд, например, текущие глобальные и локальные имена предлагаются в качестве аргументов команды p.
Вы также можете вызвать pdb из командной строки для отладки других скриптов. Например:
python -m pdb myscript.py
При вызове как модуль, pdb автоматически входит в постмортальную отладку, если программа, которая отлаживается, завершается аномально. После постмортальной отладки (или после нормального завершения программы) pdb перезапускает программу. Автоматическое перезапускание сохраняет состояние pdb (такие как точки останова) и в большинстве случаев полезнее, чем выход из отладчика по завершению программы.
Изменено в версии 3.2: Добавлен параметр -c для выполнения команд, как если бы они были указаны в файле .pdbrc; см. Команды отладчика.
Изменено в версии 3.7: Добавлен параметр -m для выполнения модулей аналогично тому, как это делает python -m. Как и со скриптом, отладчик приостановит выполнение непосредственно перед первой строкой модуля.
Типичное использование для выполнения инструкции под управлением отладчика:
>>> import pdb
>>> def f(x):
... print(1 / x)
>>> pdb.run("f(2)")
> <string>(1)<module>()
(Pdb) continue
0.5
>>>
Типичное использование для проверки аварийной программы:
>>> import pdb >>> def f(x): ... print(1 / x) ... >>> f(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in f ZeroDivisionError: division by zero >>> pdb.pm() > <stdin>(2)f() (Pdb) p x 0 (Pdb)
Изменено в версии 3.13: Реализация PEP 667 означает, что присваивания имён, сделанные через pdb, немедленно повлияют на активную область видимости, даже при работе внутри оптимизированной области видимости.
Модуль определяет следующие функции; каждая из них входит в отладчик несколько иначе:
-
pdb.run(statement, globals=None, locals=None) -
Выполнить инструкцию (переданную в виде строки или объекта кода) под управлением отладчика. Подсказка отладчика появляется до выполнения любого кода; вы можете установить точки останова и ввести
continue, или вы можете переходить по инструкции, используяstepилиnext(все эти команды описаны ниже). Дополнительные аргументы globals и locals указывают среду, в которой выполняется код; по умолчанию используется словарь модуля__main__. (См. объяснение встроенных функцийexec()илиeval().)
-
pdb.runeval(expression, globals=None, locals=None) -
Вычислить выражение (переданное в виде строки или объекта кода) под управлением отладчика. Когда
runeval()возвращает значение, возвращает значение выражения. В противном случае эта функция аналогичнаrun().
-
pdb.runcall(function, *args, **kwds) -
Вызвать функцию (объект функции или метода, а не строку) с заданными аргументами. Когда
runcall()возвращает значение, возвращает то, что вернула функция. Подсказка отладчика появляется сразу после входа в функцию.
-
pdb.set_trace(*, header=None) -
Включить отладчик в стековом фрейме вызова. Это полезно для жесткой кодировки точки останова в определенной точке программы, даже если код не отлаживается иначе (например, при сбое проверки). Если предоставлен заголовок, он выводится в консоль перед началом отладки.
Изменено в версии 3.7: Только ключевой аргумент header.
Изменено в версии 3.13:
set_trace()немедленно включит отладчик, а не на следующей строке кода, которая будет выполнена.
-
pdb.post_mortem(traceback=None) -
Перейти к постмортальной отладке заданного объекта traceback. Если traceback не указан, используется traceback текущей обрабатываемой исключительной ситуации (исключение должно обрабатываться, если используется значение по умолчанию).
-
pdb.pm() -
Перейти к постмортальной отладке исключения, найденного в
sys.last_exc.
Функции run* и set_trace() являются псевдонимами для создания экземпляра класса Pdb и вызова одноимённого метода. Если вы хотите получить доступ к дополнительным функциям, вам нужно сделать это самостоятельно:
-
class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True) -
Pdb— это класс отладчика.Аргументы completekey, stdin и stdout передаются в базовый класс
cmd.Cmd; см. описание там.Аргумент skip, если задан, должен быть итерируемым объектом шаблонов имён модулей в стиле glob. Отладчик не будет входить в фреймы, которые происходят из модуля, соответствующего одному из этих шаблонов. [1]
По умолчанию Pdb устанавливает обработчик для сигнала SIGINT (который отправляется, когда пользователь нажимает Ctrl-C в консоли) при использовании команды
continue. Это позволяет повторно войти в отладчик, нажав Ctrl-C. Если вы хотите, чтобы Pdb не трогал обработчик SIGINT, установите nosigint в true.Аргумент readrc по умолчанию равен true и определяет, будет ли Pdb загружать файлы .pdbrc из файловой системы.
Пример вызова для включения отслеживания с skip:
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
Вызывает событие аудита
pdb.Pdbбез аргументов.Изменено в версии 3.1: Добавлен параметр skip.
Изменено в версии 3.2: Добавлен параметр nosigint. Ранее Pdb никогда не устанавливал обработчик SIGINT.
Изменено в версии 3.6: Аргумент readrc.
-
run(statement, globals=None, locals=None) -
runeval(expression, globals=None, locals=None) -
runcall(function, *args, **kwds) -
set_trace() -
См. документацию по функциям, описанным выше.
-
Команды отладчика
Команды, распознаваемые отладчиком, перечислены ниже. Большинство команд можно сократить до одной или двух букв, как указано; например, h(elp) означает, что можно использовать h или help для ввода команды help (но не he или hel, ни H или Help или HELP). Аргументы команд должны быть разделены пробелами (пробелами или табуляцией). Необязательные аргументы заключены в квадратные скобки ([]) в синтаксисе команды; квадратные скобки вводить не нужно. Альтернативы в синтаксисе команды разделяются вертикальной чертой (|).
Ввод пустой строки повторяет последнюю введенную команду. Исключение: если последняя команда была командой list, перечисляются следующие 11 строк.
Команды, которые отладчик не распознает, предполагаются операторами Python и выполняются в контексте отлаживаемой программы. Операторы Python также могут быть префиксом с восклицательным знаком (!). Это мощный способ проверки отлаживаемой программы; можно даже изменить переменную или вызвать функцию. При возникновении исключения в таком операторе имя исключения выводится, но состояние отладчика не изменяется.
Изменено в версии 3.13: Выражения/операторы, префикс которых является командой pdb, теперь правильно идентифицируются и выполняются.
Отладчик поддерживает псевдонимы. Псевдонимы могут иметь параметры, что позволяет определённую степень адаптации к рассматриваемому контексту.
Несколько команд могут быть введены в одной строке, разделенные ;;. (Один ; не используется, так как он является разделителем для нескольких команд в строке, которая передаётся в парсер Python.) Интеллектуального разделения команд не применяется; входные данные разбиваются на первой паре ;; даже если она находится в середине строковой константы. Обходной путь для строк с двойными точкой с запятой — использовать неявное конкатенацию строк ';'';' или ";"";".
Для установки временной глобальной переменной используйте удобную переменную. Удобная переменная — это переменная, имя которой начинается с $. Например, $foo = 1 устанавливает глобальную переменную $foo, которую можно использовать в сеансе отладчика. Удобные переменные очищаются при возобновлении выполнения программы, поэтому они менее склонны к конфликту с вашей программой по сравнению с использованием обычных переменных, например, foo = 1.
Существует три предопределённые удобные переменные:
-
$_frame: текущий кадр, который вы отлаживаете -
$_retval: возвращаемое значение, если кадр возвращается -
$_exception: исключение, если кадр поднимает исключение
Добавлен в версии 3.12: Добавлена функция удобной переменной.
Если файл .pdbrc существует в домашнем каталоге пользователя или в текущем каталоге, он читается с кодировкой 'utf-8' и выполняется так, как если бы он был введён в приглашении отладчика, за исключением того, что пустые строки и строки, начинающиеся с #, игнорируются. Это особенно полезно для псевдонимов. Если оба файла существуют, сначала читается файл в домашнем каталоге, а псевдонимы, определённые там, могут быть переопределены локальным файлом.
Изменено в версии 3.2: .pdbrc теперь может содержать команды, которые продолжают отладку, такие как continue или next. Раньше эти команды не оказывали никакого влияния.
Изменено в версии 3.11: .pdbrc теперь читается с кодировкой 'utf-8'. Раньше он читался с кодировкой системного локали.
-
h(elp) [command] -
Без аргумента выводит список доступных команд. С аргументом команда, выводит справку по этой команде.
help pdbотображает полную документацию (строку документации модуляpdb). Поскольку аргумент команда должен быть идентификатором, необходимо ввестиhelp exec, чтобы получить справку по команде!.
-
w(here) -
Выводит трассировку стека, где самый последний кадр находится внизу. Стрелка (
>) указывает на текущий кадр, который определяет контекст большинства команд.
-
d(own) [count] -
Перемещает текущий кадр вниз по трассировке стека на count (по умолчанию 1) уровней (к более новому кадру).
-
u(p) [count] -
Перемещает текущий кадр вверх по трассировке стека на count (по умолчанию 1) уровней (к более старому кадру).
-
b(reak) [([filename:]lineno | function) [, condition]] -
С аргументом lineno устанавливает точку останова на строке lineno в текущем файле. Номер строки может быть префиксом с именем файла и двоеточием, чтобы указать точку останова в другом файле (возможно, ещё не загруженном). Файл ищется в
sys.path. Допустимые формы имени файла —/abspath/to/file.py,relpath/file.py,moduleиpackage.module.С аргументом функция устанавливает точку останова на первой исполняемой строке в данной функции. Функция может быть любым выражением, которое оценивается как функция в текущем пространстве имён.
Если присутствует второй аргумент, это выражение, которое должно оцениваться как истинное, прежде чем точка останова будет учтена.
Без аргумента выводит список всех точек останова, включая для каждой точки останова число срабатываний, текущий счётчик игнорирования и, при наличии, связанное условие.
Каждой точке останова присваивается номер, к которому ссылаются все другие команды точек останова.
-
tbreak [([filename:]lineno | function) [, condition]] -
Временная точка останова, которая автоматически удаляется при первом достижении. Аргументы такие же, как у
break.
-
cl(ear) [filename:lineno | bpnumber ...] -
С аргументом имя_файла:номер_строки очищает все точки останова в этой строке. Со списком номеров точек останова, разделенных пробелами, очищает эти точки останова. Без аргумента очищает все точки останова (но сначала спрашивает подтверждение).
-
disable bpnumber [bpnumber ...] -
Отключает точки останова, указанные в списке номеров точек останова, разделённых пробелами. Отключение точки останова означает, что она не может остановить выполнение программы, но, в отличие от удаления точки останова, она остаётся в списке точек останова и может быть (снова) включена.
-
enable bpnumber [bpnumber ...] -
Включает указанные точки останова.
-
ignore bpnumber [count] -
Устанавливает счётчик игнорирования для данного номера точки останова. Если count опущено, счётчик игнорирования устанавливается в 0. Точка останова становится активной, когда счётчик игнорирования равен нулю. Когда не равен нулю, count уменьшается каждый раз, когда достигается точка останова, и точка останова не отключена, и любое связанное условие оценивается как истинное.
-
condition bpnumber [condition] -
Устанавливает новое условие для точки останова, выражение, которое должно оцениваться как истинное, прежде чем точка останова будет учтена. Если condition отсутствует, любое существующее условие удаляется; т.е. точка останова становится безусловной.
-
commands [bpnumber] -
Указывает список команд для точки останова с номером bpnumber. Сами команды отображаются в следующих строках. Введите строку, содержащую только
endдля завершения команд. Пример:(Pdb) commands 1 (com) p some_variable (com) end (Pdb)
Чтобы удалить все команды из точки останова, введите
commandsи сразу за нимend; то есть не задавайте никаких команд.Без аргумента bpnumber,
commandsотносится к последней установленной точке останова.Вы можете использовать команды точек останова для перезапуска вашей программы. Просто используйте команду
continueилиstepили любую другую команду, которая возобновляет выполнение.Указание любой команды, возобновляющей выполнение (в настоящее время
continue,step,next,return,jump,quitи их сокращения) завершает список команд (как если бы эта команда была сразу за списком). Это происходит потому, что каждый раз, когда вы возобновляете выполнение (даже с простой командой next или step), вы можете столкнуться с другой точкой останова — которая может иметь свой собственный список команд, что приводит к неоднозначности относительно того, какой список выполнить.Если вы используете команду
silentв списке команд, стандартное сообщение о остановке на точке останова не выводится. Это может быть желательно для точек останова, которые должны вывести определённое сообщение и продолжить выполнение. Если ни одна из других команд ничего не выводит, вы не видите никаких признаков того, что точка останова была достигнута.
-
s(tep) -
Выполнить текущую строку, остановиться при первой возможности (либо в вызываемой функции, либо на следующей строке в текущей функции).
-
n(ext) -
Продолжить выполнение до достижения следующей строки в текущей функции или до ее возврата. (Разница между
nextиstepзаключается в том, чтоstepостанавливается внутри вызываемой функции, тогда какnextвыполняет вызываемые функции с (почти) полной скоростью, останавливаясь только на следующей строке в текущей функции.)
-
unt(il) [lineno] -
Без аргумента продолжить выполнение до достижения строки с номером, большим текущего.
С аргументом lineno продолжить выполнение до достижения строки с номером, большим или равным lineno. В обоих случаях также останавливаться при возврате текущей функции.
Изменено в версии 3.2: Разрешено задавать явный номер строки.
-
r(eturn) -
Продолжить выполнение до возврата текущей функции.
-
c(ont(inue)) -
Продолжить выполнение, останавливаясь только при встрече точки останова.
-
j(ump) lineno -
Установить следующую строку для выполнения. Доступно только в самом нижнем фрейме. Это позволяет перепрыгнуть назад и выполнить код еще раз или перейти вперёд, чтобы пропустить код, который не нужно запускать.
Следует отметить, что не все переходы разрешены — например, невозможно перепрыгнуть в середину цикла
forили выйти из блокаfinally.
-
l(ist) [first[, last]] -
Вывести исходный код текущего файла. Без аргументов — вывести 11 строк вокруг текущей строки или продолжить предыдущий вывод. С аргументом
.— вывести 11 строк вокруг текущей строки. С одним аргументом — вывести 11 строк вокруг строки с указанным номером. С двумя аргументами — вывести указанный диапазон; если второй аргумент меньше первого, он интерпретируется как количество строк.Текущая строка в текущем фрейме обозначена как
->. Если отлаживается исключение, строка, где исключение было первоначально возбуждено или распространено, обозначена как>>, если она отличается от текущей строки.Изменено в версии 3.2: Добавлен маркер
>>.
-
ll | longlist -
Вывести весь исходный код текущей функции или фрейма. Интересные строки отмечаются так же, как и для
list.Добавлен в версии 3.2.
-
a(rgs) -
Вывести аргументы текущей функции и их текущие значения.
-
p expression -
Вычислить выражение в текущем контексте и вывести его значение.
Примечание
print()также может быть использовано, но это не команда отладчика — это выполняет функцию Pythonprint().
-
pp expression -
Аналогично команде
p, за исключением того, что значение выражения форматируется с использованием модуляpprint.
-
whatis expression -
Вывести тип выражения.
-
source expression -
Попытаться получить исходный код выражения и отобразить его.
Добавлен в версии 3.2.
-
display [expression] -
Выводить значение выражения, если оно изменилось, каждый раз, когда выполнение останавливается в текущем фрейме.
Без выражения, вывести все выражения отображения для текущего фрейма.
Примечание
Отображение вычисляет выражение и сравнивает результат с результатом предыдущего вычисления выражения, поэтому, когда результат изменяемый, отображение может не обнаружить изменений.
Пример:
lst = [] breakpoint() pass lst.append(1) print(lst)
Отображение не поймёт, что
lstбыл изменён, потому что результат вычисления изменяется на месте модулемlst.append(1)до сравнения:> example.py(3)<module>() -> pass (Pdb) display lst display lst: [] (Pdb) n > example.py(4)<module>() -> lst.append(1) (Pdb) n > example.py(5)<module>() -> print(lst) (Pdb)
Можно использовать некоторые приёмы с механизмом копирования, чтобы это работало:
> example.py(3)<module>() -> pass (Pdb) display lst[:] display lst[:]: [] (Pdb) n > example.py(4)<module>() -> lst.append(1) (Pdb) n > example.py(5)<module>() -> print(lst) display lst[:]: [1] [old: []] (Pdb)
Добавлен в версии 3.2.
-
undisplay [expression] -
Больше не отображать выражение в текущем фрейме. Без выражения, очистить все выражения отображения для текущего фрейма.
Добавлен в версии 3.2.
-
interact -
Запустить интерактивный интерпретатор (используя модуль
code) в новом глобальном пространстве имён, инициализированном из локального и глобального пространств имён для текущего области видимости. Используйтеexit()илиquit()для выхода из интерпретатора и возврата в отладчик.Примечание
Поскольку
interactсоздаёт новое отдельное пространство имён для выполнения кода, присваивания переменным не повлияют на исходные пространства имён. Однако, изменения любых ссылающихся на изменяемые объекты будут отражены в исходных пространствах имён, как обычно.Добавлен в версии 3.2.
Изменено в версии 3.13:
exit()иquit()могут быть использованы для выхода из командыinteract.Изменено в версии 3.13:
interactнаправляет свой вывод в канал вывода отладчика, а не вsys.stderr.
-
alias [name [command]] -
Создать псевдоним с именем name, который выполняет command. command не должен быть заключён в кавычки. Заменяемые параметры могут быть указаны как
%1,%2, … и%9, а%*заменяется всеми параметрами. Если command отсутствует, отображается текущий псевдоним для name. Если аргументы не заданы, отображаются все псевдонимы.Псевдонимы могут быть вложенными и могут содержать всё, что может быть введено в командной строке pdb. Обратите внимание, что внутренние команды pdb могут быть переопределены псевдонимами. Такая команда скрывается до тех пор, пока псевдоним не будет удален. Псевдонимы применяются рекурсивно к первому слову командной строки; все остальные слова в строке остаются без изменений.
В качестве примера, вот два полезных псевдонима (особенно если разместить их в файле
.pdbrc):# Print instance variables (usage "pi classInst") alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") # Print instance variables in self alias ps pi self
-
unalias name -
Удалить указанный псевдоним name.
-
! statement -
Выполнить (однострочное) statement в контексте текущей стековой рамки. Восклицательный знак можно опустить, если первое слово оператора напоминает команду отладчика, например:
(Pdb) ! n=42 (Pdb)
Для установки глобальной переменной можно префикснуть команду присваивания оператором
globalв той же строке, например:(Pdb) global list_options; list_options = ['-l'] (Pdb)
-
run [args ...] -
restart [args ...] -
Перезапустить отлаживаемую программу Python. Если указан args, он разделится с помощью
shlex, и результат будет использован в качестве новогоsys.argv. История, точки останова, действия и параметры отладчика сохраняются.restartявляется псевдонимом дляrun.
-
q(uit) -
Выйти из отладчика. Выполняемая программа прерывается.
-
debug code -
Введите рекурсивный отладчик, который выполняет пошаговую отладку кода (произвольное выражение или оператор для выполнения в текущей среде).
-
retval -
Вывести значение возврата для последнего возврата текущей функции.
-
exceptions [excnumber] -
Список или переход между цепочками исключений.
При использовании
pdb.pm()илиPdb.post_mortem(...)с цепочкой исключений вместо трассировки стека, это позволяет пользователю перемещаться между цепочками исключений с помощью командыexceptionsдля просмотра исключений иexception <number>для перехода к этому исключению.Пример:
def out(): try: middle() except Exception as e: raise ValueError("reraise middle() error") from e def middle(): try: return inner(0) except Exception as e: raise ValueError("Middle fail") def inner(x): 1 / x out()вызов
pdb.pm()позволит переключаться между исключениями:> example.py(5)out() -> raise ValueError("reraise middle() error") from e (Pdb) exceptions 0 ZeroDivisionError('division by zero') 1 ValueError('Middle fail') > 2 ValueError('reraise middle() error') (Pdb) exceptions 0 > example.py(16)inner() -> 1 / x (Pdb) up > example.py(10)middle() -> return inner(0)Добавлен в версии 3.13.
Примечания
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/pdb.html