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); оно показывает, что вы находитесь в режиме отладки:
> ...(3)double() -> return x * 2 (Pdb) p x 3 (Pdb) continue 3 * 2 is 6
Изменено в версии 3.3: Для команд и их аргументов доступно автодополнение по нажатию Tab с помощью модуля 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)
Модуль определяет следующие функции; каждая из них запускает отладчик несколько иным способом:
-
pdb.run(statement, globals=None, locals=None) -
Выполняет statement (заданный в виде строки или объекта кода) под управлением отладчика. Приглашение отладчика появляется до выполнения какого-либо кода; можно установить точки останова и ввести
continueлибо пошагово выполнить инструкцию с помощьюstepилиnext(все эти команды описаны ниже). Необязательные аргументы globals и locals задают среду, в которой выполняется код; по умолчанию используется словарь модуля__main__. (См. описание встроенных функцийexec()илиeval().)
-
pdb.runeval(expression, globals=None, locals=None) -
Вычисляет expression (заданное в виде строки или объекта кода) под управлением отладчика. Когда
runeval()возвращает управление, она возвращает значение expression. В остальном эта функция аналогичнаrun().
-
pdb.runcall(function, *args, **kwds) -
Вызывает function (объект функции или метода, а не строку) с заданными аргументами. Когда
runcall()возвращает управление, она возвращает результат вызова функции. Приглашение отладчика появляется сразу после входа в функцию.
-
pdb.set_trace(*, header=None) -
Входит в отладчик в вызывающем кадре стека. Это позволяет жёстко задать точку останова в определённом месте программы, даже если код в остальном не отлаживается (например, при нарушении утверждения). Если указан аргумент header, он выводится в консоль непосредственно перед началом отладки.
Изменено в версии 3.7: Добавлен аргумент только по ключевому слову header.
-
pdb.post_mortem(traceback=None) -
Запускает посмертную отладку заданного объекта traceback. Если traceback не задан, используется трассировка исключения, которое обрабатывается в данный момент (для использования значения по умолчанию должно обрабатываться исключение).
-
pdb.pm() -
Запускает посмертную отладку трассировки, хранящейся в
sys.last_traceback.
Функции 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 (но не he или hel, а также не H, Help или HELP). Аргументы команд должны разделяться пробелами (пробелами или знаками табуляции). Необязательные аргументы в синтаксисе команды заключаются в квадратные скобки ([]); квадратные скобки вводить не нужно. Альтернативные варианты в синтаксисе команды разделяются вертикальной чертой (|).
Если ввести пустую строку, повторяется последняя введённая команда. Исключение: если последней командой была команда list, будут перечислены следующие 11 строк.
Команды, которые отладчик не распознаёт, считаются инструкциями Python и выполняются в контексте отлаживаемой программы. Инструкции Python также можно предварить восклицательным знаком (!). Это эффективный способ изучить отлаживаемую программу; можно даже изменить переменную или вызвать функцию. Если при выполнении такой инструкции возникает исключение, выводится его имя, но состояние отладчика не меняется.
Отладчик поддерживает псевдонимы. Псевдонимы могут принимать параметры, что позволяет в некоторой степени адаптировать их к исследуемому контексту.
В одной строке можно ввести несколько команд, разделив их с помощью ;;. (Одиночный ; не используется, поскольку он служит разделителем нескольких команд в строке, передаваемой анализатору Python.) Разделение команд не выполняет интеллектуальный анализ: ввод разбивается по первой паре ;;, даже если она находится внутри строки в кавычках. Для строк с двумя точками с запятой можно использовать неявную конкатенацию строк ';'';' или ";"";".
Если файл .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 уровней (по умолчанию на один), к более новому кадру.
-
u(p) [count] -
Перемещает текущий кадр вверх по трассировке стека на count уровней (по умолчанию на один), к более старому кадру.
-
b(reak) [([filename:]lineno | function) [, condition]] -
Если указан аргумент lineno, устанавливает точку останова на этой строке в текущем файле. Если указан аргумент function, устанавливает точку останова на первой исполняемой инструкции этой функции. Перед номером строки можно указать имя файла и двоеточие, чтобы задать точку останова в другом файле (возможно, ещё не загруженном). Файл ищется в
sys.path. Обратите внимание: каждой точке останова присваивается номер, на который ссылаются все остальные команды для работы с точками останова.Если указан второй аргумент, это выражение, которое должно иметь значение true, чтобы сработала точка останова.
Без аргумента выводит список всех точек останова, включая количество срабатываний каждой точки, текущий счётчик пропусков и связанное условие, если оно задано.
-
tbreak [([filename:]lineno | function) [, condition]] -
Временная точка останова, которая автоматически удаляется при первом срабатывании. Аргументы те же, что и у команды
break.
-
cl(ear) [filename:lineno | bpnumber ...] -
Если указан аргумент filename:lineno, удаляет все точки останова на этой строке. Если указан разделённый пробелами список номеров точек останова, удаляет эти точки. Без аргумента удаляет все точки останова (предварительно запросив подтверждение).
-
disable [bpnumber ...] -
Отключает точки останова, указанные в разделённом пробелами списке номеров. Отключённая точка останова не может остановить выполнение программы, но, в отличие от удалённой точки, остаётся в списке и может быть включена повторно.
-
enable [bpnumber ...] -
Включает указанные точки останова.
-
ignore bpnumber [count] -
Задаёт счётчик пропусков для указанного номера точки останова. Если count не указан, счётчик пропусков устанавливается в 0. Точка останова становится активной, когда счётчик пропусков равен нулю. Если счётчик ненулевой, значение count уменьшается при каждом достижении точки останова, если она не отключена и связанное с ней условие (если оно задано) истинно.
-
condition bpnumber [condition] -
Задаёт новое condition для точки останова — выражение, которое должно иметь значение true, чтобы точка останова сработала. Если 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и их сокращения) завершает список команд (как если бы сразу после этой команды следовал end). Это связано с тем, что при каждом возобновлении выполнения (даже с помощью простой команды 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 -
Вычисляет expression в текущем контексте и выводит его значение.
Примечание
Также можно использовать
print(), но это не команда отладчика — она вызывает функцию Pythonprint().
-
pp expression -
Подобна команде
p, но значение expression выводится в удобном для чтения формате с помощью модуляpprint.
-
whatis expression -
Выводит тип expression.
-
source expression -
Пытается получить исходный код expression и вывести его.
Добавлено в версии 3.2.
-
display [expression] -
Выводит значение expression, если оно изменилось, при каждой остановке выполнения в текущем кадре.
Если expression не указан, выводит список всех отслеживаемых выражений для текущего кадра.
Примечание
Команда display вычисляет expression и сравнивает результат с результатом предыдущего вычисления expression, поэтому при изменяемом результате она может не обнаружить изменения.
Пример:
lst = [] breakpoint() pass lst.append(1) print(lst)
Команда display не обнаружит изменение
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] -
Перестаёт выводить expression в текущем кадре. Если expression не указан, удаляет все отслеживаемые выражения для текущего кадра.
Добавлено в версии 3.2.
-
interact -
Запускает интерактивный интерпретатор (с помощью модуля
code), в глобальном пространстве имён которого содержатся все имена (глобальные и локальные), найденные в текущей области видимости.Добавлено в версии 3.2.
-
alias [name [command]] -
Создаёт псевдоним с именем name, выполняющий команду command. Команду command не нужно заключать в кавычки. Заменяемые параметры можно обозначить с помощью
%1,%2и так далее, а%*заменяется всеми параметрами. Если 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 в контексте текущего кадра стека. Восклицательный знак можно опустить, если только первое слово инструкции не похоже на команду отладчика. Чтобы задать глобальную переменную, можно предварить команду присваивания инструкцией
globalв той же строке, например:(Pdb) global list_options; list_options = ['-l'] (Pdb)
-
run [args ...] -
restart [args ...] -
Перезапускает отлаживаемую программу Python. Если указан аргумент args, он разбивается с помощью
shlex, а результат используется в качестве нового значенияsys.argv. История, точки останова, действия и параметры отладчика сохраняются.restart— это псевдоним дляrun.
-
q(uit) -
Завершает работу отладчика. Выполняемая программа прерывается.
-
debug code -
Запускает рекурсивный отладчик, пошагово выполняющий code (произвольное выражение или инструкцию, выполняемую в текущем окружении).
-
retval -
Выводит возвращаемое значение последнего возврата из текущей функции.
Сноски
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/pdb.html