Изучите основы и расширенные возможности использования 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)