В процессе написания кода часто допускаются ошибки. В большинстве случаев они простые, например, опечатки. Но даже подобные не позволяют вашей программе работать правильноо. Процесс исправления ошибок в программировании назвают отладкой.
Python предоставляет свой собственный встроенный отладчик pdb. Вы можете использовать pdb в командной строке или включить его в качестве модуля. Название pdb означает “Python Debugging”.
В этой статье вы познакомитесь с основами использования pdb. В частности, мы рассмотрим следующее:
- Запуск pdb с помощью REPL
- Запуск pdb с помощью командной строки
- Добавление точек останова в pdb
- Создание точки останова с помощью функции set_trace()
- Встраивание breakpoint()
Хотя pdb полезен, большинство редакторов Python имеют отладчики с более широкими возможностями. Так вы увидите, что отладчик PyCharm или WingIDE имеет гораздо больше возможностей, таких как автозавершение, подсветка синтаксиса и графический стек вызовов.
Однако бывают случаи, когда у вас может не быть Python IDE, например, при удаленной отладке на сервере. Именно в такие моменты pdb будет особенно полезен.
Содержание
Запуск pdb с помощью REPL
Лучший способ начать – это иметь под рукой код, который вы могли бы запустить в pdb. Можете взять свой собственный или пример кода из другой статьи на этом сайте.
Или вы можете создать следующий код в файле под названием debug_code.py:
# debug_code.py
def log(number):
print(f'Обработка {number}')
print(f'Прибавление 2 к числу: {number + 2}')
def looper(number):
for i in range(number):
log(i)
if __name__ == '__main__':
looper(5)
Code language: PHP (php)
Есть несколько способов начать работу с pdb. Для этого примера мы будем использовать терминал.
Переходим в папку, в которой был сохранен код.
Теперь запустим Python в терминале. Это откроет вам Python REPL, куда вы можете вставить код и запустить отладчик pdb. Вот как это выглядит:
>>> import debug_code
>>> import pdb
>>> pdb.run('debug_code.looper(5)')
> (1)()
(Pdb) continue
Обработка0
Прибавление2 к: 2
Обработка1
Прибавление2 к: 3
Обработка2
Прибавление2 к: 4
Обработка3
Прибавление2 к: 5
Обработка4
Прибавление2 к: 6
Code language: JavaScript (javascript)
Чтобы запустить pdb с вашим кодом, вы можете использовать pdb.run() и указать ему, что он должен сделать. В этом случае вы передаете debug_code.looper(5) как строку. Когда вы это сделаете, модуль pdb преобразует строку в вызов фактической функции debug_code.looper(5).
В данном случае не было установлено никаких исключений или точек останова, поэтому код отработал и завершил выполнение.
Запуск pdb в командной строке
Альтернативный способ запуска pdb – через командную строку. Процесс запуска pdb таким образом аналогичен предыдущему методу. Для этого нужно открыть терминал и перейти в папку, в которой вы сохранили файл.
Ведите следующее:
python -m pdb debug_code.py
Code language: CSS (css)
Когда вы запустите pdb, результат будет другим:
> /python101code/chapter26_debugging/debug_code.py(1)()
-> def log(number):
(Pdb) continue
Обработка0
Прибавление2 к: 2
Обработка1
Прибавление2 к: 3
Обработка2
Прибавление2 к: 4
Обработка3
Прибавление2 к: 5
Обработка4
Прибавление2 к: 6
The program finished and will be restarted
> /python101code/chapter26_debugging/debug_code.py(1)()
-> def log(number):
(Pdb) exit
Code language: JavaScript (javascript)
Отладчик завершил выполнение всего вашего кода, а затем начал с самого начала! Это полезно для многократного выполнения программы! Если вы не хотите запускать код повторно, вы можете набрать exit, чтобы выйти из отладчика.
Добавление точек останова в pdb
Точка останова – это место в коде, где отладчик должен остановиться, чтобы проверить состояние переменных. Это позволит вам просмотреть стек вызовов для всех переменных и аргументов функций, которые в настоящее время находятся в памяти.
Если у вас есть PyCharm или WingIDE, то в них есть графический способ, позволяющий осмотреть стек вызовов. Вы можете навести курсор на переменные, чтобы увидеть, какие значения они имеют в данный момент. Или они могут использовать инструмент, который перечисляет все переменные на боковой панели.
Давайте добавим точку останова на последнюю строку looper().
# debug_code.py
def log(number):
print(f'Обработка {number}')
print(f'Прибавление 2 к числу: {number + 2}')
def looper(number):
for i in range(number):
log(i)
if __name__ == '__main__':
looper(5)
Code language: PHP (php)
Чтобы установить точку останова в отладчике pdb, вы можете использовать команду break или b, за которой следует номер строки, на которой вы хотите прерваться:
$ python3.8 -m pdb debug_code.py
> /python101code/chapter26_debugging/debug_code.py(3)()
-> def log(number):
(Pdb) break 10
Breakpoint 1 at /python101code/chapter26_debugging/debug_code.py:10
(Pdb) continue
> /python101code/chapter26_debugging/debug_code.py(10)looper()
-> log(i)
(Pdb)
Code language: JavaScript (javascript)
Создание точки останова с помощью функции set_trace()
Отладчик Python позволяет вам импортировать модуль pbd и добавить точку останова в ваш код напрямую:
def log(number):
print(f'Обработка {number}')
print(f'Прибавление 2 к числу: {number + 2}')
def looper(number):
for i in range(number):
import pdb; pdb.set_trace()
log(i)
if __name__ == '__main__':
looper(5)
Code language: PHP (php)
Теперь, когда вы запустите этот код в терминале, он автоматически запустит pdb, когда дойдет до вызова функции set_trace():
$ python3.8 debug_code_with_settrace.py
> /python101code/chapter26_debugging/debug_code_with_settrace.py(12)looper()
-> log(i)
(Pdb)
1
2
3
4
$ python3.8 debug_code_with_settrace.py
> /python101code/chapter26_debugging/debug_code_with_settrace.py(12)looper()
-> log(i)
(Pdb)
Code language: JavaScript (javascript)
Это требует добавления большого количества дополнительного кода, который впоследствии придется удалить. Вы также можете столкнуться с проблемами, если забудете поставить точку с запятой между импортом и вызовом pdb.set_trace().
Чтобы облегчить работу, разработчики ядра Python добавили функцию breakpoint(), которая эквивалентна набору import pdb; pdb.set_trace().
Использование функции breakpoint()
Начиная с Python 3.7, вы можете использовать функцию breakpoint().
Ниже приводится обновление кода с использованием этой функции.
# debug_code_with_breakpoint.py
def log(number):
print(f'Обработка {number}')
print(f'Прибавление 2 к числу: {number + 2}')
def looper(number):
for i in range(number):
breakpoint()
log(i)
if __name__ == '__main__':
looper(5)
1
2
3
4
5
6
7
8
9
10
11
12
# debug_code_with_breakpoint.py
def log(number):
print(f'Обработка {number}')
print(f'Прибавление 2 к числу: {number + 2}')
def looper(number):
for i in range(number):
breakpoint()
log(i)
if __name__ == '__main__':
looper(5)
Code language: PHP (php)
Теперь, когда вы запустите это в терминале, pdb запустится точно так же, как и раньше.
Еще одним преимуществом использования функции breakpoint() является то, что многие IDE Python распознают эту функцию и автоматически приостанавливают выполнение. Это означает, что в этот момент вы можете использовать встроенный отладчик IDE для отладки. Э
Заключение
Для того чтобы успешно отлаживать свой код, необходима практика. Очень хорошо, что Python предоставляет вам возможность отладки кода без установки дополнительных программ.