Изучите основы и расширенные возможности использования pdb, чтобы повысить свою производительность.

Если вы живете в своем shell (каламбур), вы должны знать о самом старшем ребенке в блоке, pdb (Python Debugger), который является почти аналогом gdb. (Отладчик GNU)inC/C++ .

Pdb — самый мощный отладчик, который вы только можете себе представить, и его освоение произведет революцию в ваших навыках разработки.

Если вам понравился pdb, вам понравится и pdb++. Отладчик pdb++ расширяет базовые функциональные возможности pdb некоторыми полезными функциями, наиболее важной из которых является подсветка синтаксиса. На момент написания этой статьи последней версией pdb++ была 0.10.3 .

В этом руководстве основное внимание уделяется Python 3.7+, так как pdb получил некоторые улучшения в версиях 3.2 и 3.7. Мы будем использовать термины pdb и pdb++ взаимозаменяемо, предполагая, что pdb++ установлен и является отладчиком по умолчанию для вашей среды Python.

Оглавление

· Как установить pdb++?
· Основы использования pdb
∘ Установить точку останова
∘ Отключить все точки останова
∘ Отладка после смерти< br /> · Команды Pdb и Pdb++
∘ Навигация по исходному коду
∘ Изучение контекста
∘ Перемещение между стеками
· Переход к контрольным точкам< br /> ∘ Точка останова по строке
∘ Список всех точек останова
∘ Очистить все точки останова
∘ Точка останова по модулю (файлу)
∘ Точка останова по функция
∘ Точка останова по условию
∘ Временная точка останова (tbreak)
∘ Выполнение кода

Как установить pdb++?

Вы можете установить pdb++ через менеджеры пакетов pip или conda (последняя версия на момент написания этого поста была 0.10.3):

pip install pdbpp                   # install via pip
conda install -c conda-forge pdbpp  # install via conda

pdb++ будет автоматически использоваться во всех местах, где использовалось pdb. Поскольку pdb++ — это всего лишь оболочка над pdb, обычный модуль pdb по-прежнему доступен как import pdb; pdb.pdb.

Основы Варианты использования pdb

Установить точку останова

В Python 3.7+ точку останова можно установить, вызвав встроенную функцию breakpoint(). Выполнение модуля python будет приостановлено на breakpoint() строке, а pdb будет запущено.

В более старых версиях Python точки останова создавались вызовом функции set_trace() модуля pdb ( from pdb import set_trace; set_trace ).

Примечание. Узнайте о расширенном использовании точки останова и команды b[reakpoint] в разделе Дополнительные точки останова.

Отключить все точки останова

Установка для переменной среды PYTHONBREAKPOINT значения 0 отключит все точки останова в коде, что намного проще, чем вручную комментировать их в коде. Это полезная функция при отключении нескольких точек останова во время отладки.

python -c "breakpoint()"
# Will pause execution at the breakpoint and start the debugger

PYTHONBREAKPOINT=0 python -c "breakpoint()"
# Skips the breakpoint

Посмертная отладка

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

python -m pdb foo.py

Это приостановит выполнение в самом начале и будет ожидать команды continue (c или cont) от пользователя (см. раздел Команды Pdb). Чтобы пропустить начальную паузу, запустите с флагом -c continue:

python -m pdb -c continue foo.py

Предварительное примечание. В Python 3.7+ pdb принимает флаг -m; поэтому модуль bar в пакете foo можно вызвать с помощью:

python -m foo.bar
python -m pdb -m foo.bar

Бонус: чтобы узнать о флаге -m в Python, прочитайте этот ответ на StackOverflow.

Команды Pdb и Pdb++

Когда запускается pdb, разработчик может начать проверку состояния выполнения. Чтобы получить список доступных команд, попробуйте help или h. Большинство команд можно сократить до одной или двух букв, как указано; например, h(elp) или cl(ear). Обе формы эквивалентны.

Подробное описание всех команд отладчика доступно в pdb справочниках: https://docs.python.org/3/library/pdb.html. Здесь мы обсудим самые полезные из них.

Функциональность команд демонстрируется с помощью фрагмента кода bar.pycode. Обратите внимание на breakpoint() в func3.

# foo/bar.py

def func3(sky, ocean, sea):
    breakpoint()
    print('func1', sky, ocean, sea)


def func2(sky, ocean):
    # This is a long docstring to enable scrolling.
    #
    #
    #
    #
    # end of docstring
    func3(sky, ocean, 3)


def func1(sky):
    func2(sky, 2)


func1(1)

Навигация по исходному коду

l[ist]: перечисляет 11 строк вокруг текущей строки или продолжает предыдущий список. Индикатор -> указывает место, где выполнение приостановлено. List не является идемпотентной функцией и итеративно извлекает следующие 11 строк модуля.

✦ ❯ python foo/bar.py
[3] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(5)func3()
-> print('func1', sky, ocean, sea)
(Pdb++) l
  1   # foo/bar.py
  2
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->     print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9       # This is a long docstring to enable scrolling.
 10       #
 11       #

(Pdb++) l
 12       #
 13       #
 14       # end of docstring
 15       func3(sky, ocean, 3)
 16
 17
 18   def func1(sky):
 19       func2(sky, 2)
 20
 21
 22   func1(1)

(Pdb++) l
[EOF]

Предварительное примечание. Чтобы сбросить итератор обратно в начало, попробуйте: l .

(Pdb++) l.
  1   # foo/bar.py
  2
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->     print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9       # This is a long docstring to enable scrolling.
 10       #
 11       #

ll (длинный список): идемпотентная и более умная альтернатива l[ist], которая показывает строки активной функции.

(Pdb++) ll
   3     def func3(sky, ocean, sea):
   4         breakpoint()
   5  ->     print('func1', sky, ocean, sea)

(Pdb++) ll
   3     def func3(sky, ocean, sea):
   4         breakpoint()
   5  ->     print('func1', sky, ocean, sea)

источник:команду source можно использовать для получения исходного кода модуля, класса, метода, функции, трассировки, фрейма или кода.

Представьте следующее определение класса в модуле foo.my_class:

Обязательно импортируйте модуль/класс, прежде чем запрашивать его исходный код:

(Pdb++) from foo.my_class import MyClass
(Pdb++) source MyClass
   3     class MyClass:
   4         """A delicate class indeed!"""
   5         pass

Команда source также может получать исходный код объектов из других пакетов.

(Pdb++) import numpy
(Pdb++) source numpy
   0     """
   1     NumPy
   2     =====
   3
   4     Provides
   5       1. An array object of arbitrary homogeneous items
   6       2. Fast mathematical operations over arrays
   7       3. Linear Algebra, Fourier Transforms, Random Number Generation
   8
   9     How to use the documentation
  10     ----------------------------
  11     Documentation is available in two forms: docstrings provided
  12     with the code, and a loose standing reference guide, available from
  13     `the NumPy homepage <https://www.scipy.org>`_.
  14
  15     We recommend exploring the docstrings using
  16     `IPython <https://ipython.org>`_, an advanced Python shell with
  17     TAB-completion and introspection capabilities.  See below for further
  18     instructions.

Изучение контекста

locals(): хотя это и не команда pdb, встроенная функция locals() в Python является полезным инструментом отладки для получения текущей таблицы локальных символов.

(Pdb++) ll
   3     def func3(sky, ocean, sea):
   4         breakpoint()
   5  ->     print('func1', sky, ocean, sea)

(Pdb++) locals()
{'sky': 1, 'ocean': 2, 'sea': 3}

Выражения и операторы. Любое выражение и оператор Python допустимы в pdb, включая присваивания.

(Pdb++) locals()
{'sky': 1, 'ocean': 2, 'sea': 3}

(Pdb++) my_var = sum([v for k,v in locals().items()])
(Pdb++) locals()
{'sky': 1, 'ocean': 2, 'sea': 3, 'my_var': 6}

? (проверить): чтобы узнать больше о переменной, используйте ? после ее имени (например, my_var?) или используйте inspect (например, inspect my_var).

(Pdb++) sky
1

(Pdb++) sky?
Type:           int
String Form:    1
Docstring:      int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

a[rgs]:распечатать список аргументов текущей функции.

(Pdb++) ll
   3     def func3(sky, ocean, sea):
   4         breakpoint()
   5  ->     print('func1', sky, ocean, sea)

(Pdb++) args
sky = 1
ocean = 2
sea = 3

(Pdb++)

pp: pp делает то, что говорит, красиво печатает, и в основном полезен при работе с большими контейнерами.

(Pdb++) {i:i for i in range(1000, 1020)}
{1000: 1000, 1001: 1001, 1002: 1002, 1003: 1003, 1004: 1004, 1005: 1005, 1006: 1006, 1007: 1007, 1008: 1008, 1009: 1009, 1010: 1010, 1011: 1011, 1012: 1012, 1013: 1013, 1014: 1014, 1015: 1015, 1016: 1016, 1017: 1017, 1018: 1018, 1019: 1019}

(Pdb++) pp {i:i for i in range(1000, 1020)}
{1000: 1000,
 1001: 1001,
 1002: 1002,
 1003: 1003,
 1004: 1004,
 1005: 1005,
 1006: 1006,
 1007: 1007,
 1008: 1008,
 1009: 1009,
 1010: 1010,
 1011: 1011,
 1012: 1012,
 1013: 1013,
 1014: 1014,
 1015: 1015,
 1016: 1016,
 1017: 1017,
 1018: 1018,
 1019: 1019}
(Pdb++)

Перемещение между стопками

w[here]:распечатайте стопку с самым последним кадром внизу. Символ _53 указывает на текущий кадр.

(Pdb++) w
[0]   /Users/amirabdi/pdb_like_a_pro/foo/bar.py(22)<module>()
-> func1(1)
[1]   /Users/amirabdi/pdb_like_a_pro/foo/bar.py(19)func1()
-> func2(sky, 2)
[2]   /Users/amirabdi/pdb_like_a_pro/foo/bar.py(15)func2()
-> func3(sky, ocean, 3)
[3] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(5)func3()
-> print('func1', sky, ocean, sea)

Приведенная выше трассировка стека показывает, что мы в настоящее время находимся в func3() в строке 3 модуля bar.py, а следующая строка, которая должна быть выполнена, — print(...).

u[p]: переход на один кадр вверх.

(Pdb++) l .
  1   # foo/bar.py
  2
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->   print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9       func3(sky, ocean, 3)
 10
 11

(Pdb++) u
[2] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(9)func2()
-> func3(sky, ocean, 3)

(Pdb++) l .
  4       breakpoint()
  5       print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9  ->   func3(sky, ocean, 3)
 10
 11
 12   def func1(sky):
 13       func2(sky, 2)

d[own]: перейти на один кадр вниз.

(Pdb++) l .
  4       breakpoint()
  5       print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9  ->   func3(sky, ocean, 3)
 10
 11
 12   def func1(sky):
 13       func2(sky, 2)
 14

(Pdb++) d
[3] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(5)func3()
-> print('func1', sky, ocean, sea)

(Pdb++) l .
  1   # foo/bar.py
  2
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->   print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9       func3(sky, ocean, 3)

f[frame] ‹NUM›: переход к указанному номеру кадра. Пример f 3 переходит к номеру кадра 3.

(Pdb++) f 0
[0] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(16)<module>()
-> func1(1)
(Pdb++) l .
 11
 12   def func1(sky):
 13       func2(sky, 2)
 14
 15
 16  -> func1(1)
[EOF]

(Pdb++) f 3
[3] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(5)func3()
-> print('func1', sky, ocean, sea)
(Pdb++) l .
  1   # foo/bar.py
  2
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->   print('func1', sky, ocean, sea)
  6
  7
  8   def func2(sky, ocean):
  9       func3(sky, ocean, 3)

Предварительные точки останова

Вы можете установить точку останова с помощью команды b[reakpoint]pdb. Это очень мощный инструмент; овладение навыком точки останова поможет вам очень далеко в жизни!

Точка останова на строке

Точку останова можно установить в строке текущего модуля с помощью команды b, например b <line_number>.

(Pdb++) b 9
Breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:9

(Pdb++) b 13
Breakpoint 2 at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:13

Когда установлена ​​новая точка останова, pdb подтверждает это.

Список всех точек останова

Команда b без каких-либо аргументов выводит список всех точек останова, исключая точки останова, которые вы жестко запрограммировали в исходном коде с помощью breakpoint() .

(Pdb++) b
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:14
 breakpoint already hit 1 time
2   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:9

Здесь pdb сообщает вам, что b в строке 14 «сработало» один раз.

Удалить все точки останова

Команда cl[ear] удаляет точки останова:

  • cl : удаляет все точки останова из всех модулей
(Pdb++) b
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:14
 breakpoint already hit 1 time
2   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:9

(Pdb++) cl
Clear all breaks? yes
Deleted breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:14
Deleted breakpoint 2 at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:9

(Pdb++) b
(Pdb++)
  • cl <breakpoint_number> : удаляет указанную точку останова
(Pdb++) b
Num Type         Disp Enb   Where
3   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:14
4   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:9

(Pdb++) cl 3
Deleted breakpoint 3 at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:14

(Pdb++) b
Num Type         Disp Enb   Where
4   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:9

Точки останова по модулям (файлам)

По умолчанию точки останова устанавливаются на текущий модуль. Чтобы установить точку останова в другом файле, используйте путь к модулю. Например,

(Pdb++) b /path/to/foo.py:10

устанавливает точку останова в строке 10 файла foo.py.

Точка останова по функции

Команда b <function_name> установит точку останова на самой первой исполняемой строке данной функции. Функция уже должна быть импортирована в текущей области видимости и может быть из сторонней библиотеки.

В приведенном ниже примере команда b func2 устанавливает точку останова в строке 7, которая останавливает выполнение в строке 16 модуля bar.py.

# run in post-mortem to pause at the beginning
✦ ❯ python -m pdb foo/bar.py
[2] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(3)<module>()
-> def func3(sky, ocean, sea):

(Pdb++) l .
  3  -> def func3(sky, ocean, sea):
  4       print('func1', sky, ocean, sea)
  5
  6
  7   def func2(sky, ocean):
  8       func3(sky, ocean, 3)
  9
 10
 11   def func1(sky):

(Pdb++) b func2
Breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/foo/bar.py:7

(Pdb++) cont
[4] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(8)func2()
-> func3(sky, ocean, 3)

(Pdb++) l .
  3   def func3(sky, ocean, sea):
  4       print('func1', sky, ocean, sea)
  5
  6
  7 B def func2(sky, ocean):
  8  ->   func3(sky, ocean, 3)
  9
 10
 11   def func1(sky):
 12       func2(sky, 2)

Этот подход можно даже использовать для установки точек останова в функциях сторонних библиотек. Например, следующий сценарий использует библиотеку requests:

# call.py
import requests
breakpoint()
requests.get('https://google.com')

Разработчик может установить точку останова в начале функции get с помощью команды b requests.get и проверить ее следующим образом.

✦ ❯ python call.py
[0] > /Users/amirabdi/pdb_like_a_pro/call.py(4)<module>()
-> requests.get('https://google.com')

(Pdb++) b requests.get
Breakpoint 1 at /Users/amirabdi/miniconda3/lib/python3.7/site-packages/requests/api.py:64

(Pdb++) cont
[1] > /Users/amirabdi/miniconda3/lib/python3.7/site-packages/requests/api.py(75)get()
-> kwargs.setdefault('allow_redirects', True)

(Pdb++) l
 70       :param \*\*kwargs: Optional arguments that ``request`` takes.
 71       :return: :class:`Response <Response>` object
 72       :rtype: requests.Response
 73       """
 74
 75  ->     kwargs.setdefault('allow_redirects', True)
 76       return request('get', url, params=params, **kwargs)
 77
 78
 79   def options(url, **kwargs):
 80       r"""Sends an OPTIONS request.

Посмотрите, как мы используем команду ll для проверки исходного кода.

Точка останова по условию

Условные точки останова устанавливаются с помощью команды b <where>, <condition> и срабатывают только при выполнении условия.

Представьте себе следующую рекурсивную функцию Фибоначчи:

# fibonnaci.py
def recur_fibo(value):
   if value <= 1:
       return value
   else:
       return(recur_fibo(value-1) + recur_fibo(value-2))

recur_fibo(10)

Точка останова может быть установлена ​​в зависимости от value == 5 as, и условия отображаются в списке точек останова:

✦ ❯ python -m pdb fibonacci.py
[2] > /Users/amirabdi/pdb_like_a_pro/fibonacci.py(2)<module>()
-> def recur_fibo(value):

(Pdb++) b recur_fibo, value == 5
Breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:2

(Pdb++) b
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:2
 stop only if value == 5

Если выполнение продолжить (cont), оно остановится только при выполнении условия:

✦ ❯ python -m pdb fibonacci.py
[2] > /Users/amirabdi/pdb_like_a_pro/fibonacci.py(2)<module>()
-> def recur_fibo(value):

(Pdb++) b recur_fibo, value == 5
Breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:2

(Pdb++) b
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:2
 stop only if value == 5

(Pdb++) cont
[8] > /Users/amirabdi/pdb_like_a_pro/fibonacci.py(3)recur_fibo()
-> if value <= 1:

(Pdb++) l .
  1   # fibonnaci.py
  2 B def recur_fibo(value):
  3  ->  if value <= 1:
  4          return value
  5      else:
  6          return(recur_fibo(value-1) + recur_fibo(value-2))
  7
  8   recur_fibo(10)
[EOF]

(Pdb++) value
5

Расширенный вопрос: в recur_fibo(10) и условной точке останова b recur_fibo, value == 5 сколько раз выполнение будет приостановлено в указанной точке останова?

Ответ: 8

Временная точка останова (tbreak)

Временная точка останова устанавливается с помощью команды tbreak и прерывает выполнение только один раз.

В приведенном выше примере рекурсивного Фибоначчи точка останова устанавливается с помощью команды commandtbreak recur_fibo и удаляется автоматически сразу после первого попадания:

~/pdb_like_a_pro via 🐍 v3.7.4 via C base on ☁️  us-west-2 took 3m37s
✦ ❯ python -m pdb fibonacci.py
[2] > /Users/amirabdi/pdb_like_a_pro/fibonacci.py(2)<module>()
-> def recur_fibo(value):

(Pdb++) tbreak recur_fibo
Breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:2

(Pdb++) cont
Deleted breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:2
[3] > /Users/amirabdi/pdb_like_a_pro/fibonacci.py(3)recur_fibo()
-> if value <= 1:

(Pdb++) value
10

(Pdb++) cont
The program finished and will be restarted

Временные точки останова помечаются как del в списке точек останова:

(Pdb++) tbreak 5
Breakpoint 1 at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:5
(Pdb++) break 6
Breakpoint 2 at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:6

(Pdb++) b
Num Type         Disp Enb   Where
1   breakpoint   del  yes   at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:5
2   breakpoint   keep yes   at /Users/amirabdi/pdb_like_a_pro/fibonacci.py:6

Выполнение кода

Для управления выполнением кода можно использовать следующие команды pdb: step, next, until, return, continue и jump. Вот краткий обзор наиболее полезных из них: step, next, return и until.

s[tep] vs n[ext]: `step` переходит к вызовам функций, а `next` проходит через них.

step (шаг внутрь): Команда step выполняет текущую строку и переходит в вызываемую функцию или останавливается на следующей строке в текущей функции.

(Pdb++) l .
  6
  7   def func2(sky, ocean):
  8       x = 10
  9       y = x
 10       breakpoint()
 11  ->   func3(sky, ocean, 3)
 12       z = y
 13       alpha = sum([x, y, z])
 14
 15
 16   def func1(sky):

(Pdb++) s
--Call--
[5] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(3)func3()
-> def func3(sky, ocean, sea):

(Pdb++) l .
  1   # foo/bar.py
  2
  3 -> def func3(sky, ocean, sea):
  4       print('func1', sky, ocean, sea)
  5
  6
  7    def func2(sky, ocean):
  8       x = 10
  9       y = x
 10       breakpoint()
 11       func3(sky, ocean, 3)
  • next(переход): команда next продолжает выполнение до тех пор, пока не будет достигнута следующая строка в текущей функции, поэтому она обходитвызовы функций.
(Pdb++) l .
  6
  7   def func2(sky, ocean):
  8       x = 10
  9       y = x
 10       breakpoint()
 11  ->   func3(sky, ocean, 3)
 12       z = y
 13       alpha = sum([x, y, z])
 14
 15
 16   def func1(sky):

(Pdb++) n
func1 1 2 3
[4] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(12)func2()
-> z = y

(Pdb++) l .
  7   def func2(sky, ocean):
  8       x = 10
  9       y = x
 10       breakpoint()
 11       func3(sky, ocean, 3)
 12  ->   z = y
 13       alpha = sum([x, y, z])
 14
 15
 16   def func1(sky):
 17       func2(sky, 2)

r[return]:продолжать выполнение, пока текущая функция не вернется.

✦ ❯ python -m foo.bar
[5] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(5)func3()
-> x = 10

(Pdb++) l .
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->   x = 10
  6       y = x
  7       z = y
  8       alpha = sum([x, y, z])
  9       print('func1', sky, ocean, sea)
 10

(Pdb++) return
func1 1 2 3
--Return--
[5] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(9)func3()->None
-> print('func1', sky, ocean, sea)

(Pdb++) l .
  4       breakpoint()
  5       x = 10
  6       y = x
  7       z = y
  8       alpha = sum([x, y, z])
  9  ->    print('func1', sky, ocean, sea)
 10
 11
 12   def func2(sky, ocean):
 13       func3(sky, ocean, 3)
 14

unt[il] ‹line_number›:Команда until продолжает выполнение до тех пор, пока не достигнет строки с номером, превышающим указанный аргумент line_number. Если аргумент не указан, по умолчанию используется текущая строка. Это особенно полезно, когда вы хотите перейти после цикла.

(Pdb++) l .
  1   # foo/bar.py
  2
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5  ->     x = 10
  6       y = x
  7       z = y
  8       alpha = sum([x, y, z])
  9       print('func1', sky, ocean, sea)
 10
 11

(Pdb++) until 8
[5] > /Users/amirabdi/pdb_like_a_pro/foo/bar.py(8)func3()
-> alpha = sum([x, y, z])

(Pdb++) l .
  3   def func3(sky, ocean, sea):
  4       breakpoint()
  5       x = 10
  6       y = x
  7       z = y
  8  ->     alpha = sum([x, y, z])
  9       print('func1', sky, ocean, sea)
 10
 11
 12   def func2(sky, ocean):
 13       func3(sky, ocean, 3)