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