- Как использовать отладчик pdb для Python приложений
- Отладка Python-кода с помощью print
- Команды Python-отладчика
- up(p) и down(d)
- step() и next()
- break()
- Продолжаем изучать Python-отладчик
- Отладка кода Django
- Профилирование и отладка Python, отладка
- Классика жанра
- The Python Debugger
- IPython pdb
- debug
- ipdbplugin
- werkzeug
- django-pdb
- django-extensions
- sentry
- Winpdb
Как использовать отладчик pdb для Python приложений
pdb — это встроенный отладчик для Python, который, в отличие от print() , позволяет отлаживать программу в процессе её работы.
Отладка Python-кода с помощью print
Как уже говорилось ранее, кто-то используют print() для отображения информации, которая помогает понять, что происходит в коде. Кто-то использует логи для тех же целей, но давайте не путать использование логов на продакшене и случаи, когда их используют во время поиска багов в коде и после удаляют.
Но самая большая проблема в использовании print() — это необходимость вносить изменения в код и перезапускать приложение, чтобы увидеть изменения. Давайте разберёмся, почему отладчики эффективнее.
Команды Python-отладчика
Главная задача отладчика — предоставить возможность заглянуть в процесс выполнения кода. Так, например, можно просмотреть стек вызовов, узнать значения переменных, установить брейкпоинты или запустить выполнение кода построчно. Можно провести аналогию с тем, как автомеханик заглядывает под капот автомобиля и начинает перебирать деталь за деталью, пока не найдет причину поломки.
Если вы работаете с Python, то можете не только просматривать код во время отладки, но даже запускать код из командной строки или изменять значения переменных на лету.
FBS , Санкт-Петербург , По итогам собеседования
Python есть встроенный отладчик под названием pdb. Это простая консольная утилита, которая обладает основной функциональностью для отладки кода. Но если вы ищете что-то более продвинутое, то стоит обратить внимание на ipdb – отладчик с функциональностью из IPython.
Проще всего вызвать отладчик pdb из кода, где вы работаете:
Как только интерпретатор доберётся до этой строчки, запустится отладчик и в консоли будут доступны новые команды.
Эта команда покажет часть кода, на выполнении которой сейчас находится интерпретатор. Можно передать два аргумента first и last для просмотра определённого участка кода. Если указать только first, то будет выведен код вокруг искомой строки.
up(p) и down(d)
Эти команды используются для передвижения по стеку вызовов. С их помощью можно отследить, откуда была вызвана текущая функция.
step() и next()
Другая пара не менее важных команд. С их помощью можно выполнять код построчно. Единственное различие между ними в том, что next() перейдёт к следующей строке вне зависимости от вызываемых функций, а step() перейдёт в вызванную функцию, если это возможно.
break()
Эта команда позволяет создавать брейкпоинты без внесений изменений в код. Ниже разберём этот этап более детально.
Краткий список команд отладчика pdb:
- args() — выводит аргументы функции;
- continue() или (cont) — продолжит выполнение до первого брейкпоинта или до завершения программы;
- help() — выводит список доступных команд или подсказки по определённой команде;
- jump() — перепрыгивает к выполнению указанной строчки кода;
- list() — выводит исходный код программы вокруг выбранной строки;
- expression() — выводит значение выражения;
- pp — выводит значение в «красивом» виде;
- quit или exit() — отменяет выполнение программы;
- return() — завершает выполнение текущей функции.
Продолжаем изучать Python-отладчик
Рассмотренный ранее способ работы с отладчиком требовал внесения изменения в код для вывода чего-нибудь или установки брейкпоинта. Но часто при работе с внешними библиотеками появляется необходимость в их отладке. Конечно, можно открыть исходный код библиотеки и вызвать pdb .
Но теперь есть возможность запускать приложение напрямую из отладчика без внесения изменения в код. Для этого воспользуемся следующей командой:
Давайте разберём на примере. Есть простое приложение, которое отслеживает рабочее время. Для её работы используется библиотека requests , отвечающая за выполнение HTTP-запросов. Попробуем прервать выполнение во время запроса. Как это сделать? Запустим приложение через отладчик и установим брейкпоинт внутри библиотеки requests .
Как можно заметить, не нужно указывать полный путь до библиотеки. Можно указать относительную ссылку от sys.path . Таким же образом можно отлаживать и ваше приложение.
Теперь куда проще отлаживать код. Не надо вносить изменения в приложение или во внешние библиотеки.
Но что делать, если в приложении происходит много вызовов, а вам надо обработать только какой-то определённый? Можно точно указать условие, при выполнении которого отладчик будет прерывать выполнение приложения.
В данном примере прерывание произойдёт только в случае, если json будет иметь в себе ключ time_entry .
Отладка кода Django
Если вы используете Django, то скорее всего знаете, что, если в настройках значение параметра DEBUG установлено как True , то для каждого исключения будет выводиться отдельная страница с указанием типа исключения, стек вызовов, локальные переменные и т.д.
Если вы хотите прокачать отладчик, то установите django-extensions и используйте команду runserver_plus для запуска сервера. Также можно указать пароль для доступа к отладке следующей командой:
Прим. перев. В Werkzeug, начиная с версии 0.11, появилась возможность доступа по паролю к отладчику. Это сделано для повышения безопасности при попытках несанкционированного доступа.
Если вы используете django-extensions, то получите страницу со всеми вызовами, кодом и окном отладчика.
Процесс отладки осуществляется с помощью WSGI библиотеки Werkzeug.
Существует множество способов отладки приложений, но специализированные инструменты могут дать вам огромное преимущество по сравнению с другими разработчиками и помогут сэкономить время и силы при поиске багов. Cреды разработки предлагают широкий выбор средств отладки, подробнее о них в нашей подборке лучших IDE и редакторов кода для Python.
Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.
Перейти к регистрации
Источник
Профилирование и отладка Python, отладка
В предыдущей статье мы закончили разговор о профилировании обзором событийных профайлеров.
Сегодня я предлагаю рассмотреть методы отладки программ.
- Введение и теория — зачем вообще нужно профилирование, различные подходы, инструменты и отличия между ними
- Ручное и статистическое профилирование — переходим к практике
- Событийное профилирование — инструменты и их применение
- Отладка — что делать, когда ничего не работает
Прежде, чем начинать разговор об отладке, нам нужно определиться, что же это такое. По традиции, обратимся к Википедии: «Отладка — обнаружение, локализация и устранение ошибок». Вообще, для успешной отладки программы, нам необходимо (но не всегда достаточно) две вещи: значение переменных в том месте программы, в котором произошла ошибка, а так же стектрейс: порядок вызова функций, вплоть до ошибочной. Полезно так же знать об окружении, в котором выполняется программа: наличие (или отсутствие) свободной памяти, системные ограничения (например, на количество файловых дескрипторов) и так далее, но это слегка выходит за пределы нашей статьи.
Классика жанра
Что делает начинающий программист, когда хочет «проникнуть» внутрь программы и изучить содержимое переменных (в нужных местах) и логику работы программы (вызовы функций, выполнение условий)? Он прибегает к самому распространённому, самому простому и самому «действенному» способу отладки: расставляет по всему коду «принты» (оператор print в Python 2.x и функция print() в Python 3.x). Но не только начинающие грешат этим: продвинутые разработчики частенько ленятся использовать специальные инструменты для отладки, надеясь быстренько, за пару минут, найти причину ошибки и всё исправить, и не замечая, что поиски ошибок растягиваются на часы и даже дни. Кстати, такой подход называют «журналированием».
Сюда же относится запись всей нужной для отладки программы информации в лог-файл. Иногда других вариантов нет, например, когда скрипт работает в продакшене и ошибки возникают эпизодически, или когда ошибка проявляется только после долгой работы программы (скажем, через две-три недели после запуска).
Но мы же пишем на Python, так почему бы не воспользоваться встроенными средствами отладки или инструментами, предлагаемыми сообществом? Например, вместо обычного логгирования в файл имеет смысл использовать Sentry, чтобы кроме сообщения об ошибке можно было отправить дополнительную информацию: стектрейс со всеми локальными переменными, любые другие переменные и вообще всё, что посчитаете нужным.
The Python Debugger
Python имеет встроенный отладчик: модуль pdb. В принципе, на этом можно было бы закончить статью, т.к. pdb — чрезвычайно мощный отладчик и всё остальное, по сути, всего лишь «украшательства» к нему. Но мы продолжим =)
Как можно заметить из названия, pdb многое взял от gdb (GNU Project debugger) — отладчика Си (и не только) программ. К слову, программы на Python можно отлаживать и с помощью gdb, просто это немножко сложнее и дольше, хотя тем, кто хочет углубиться в устройство языка, а так же тем, кто пишет сишные модули для питона без gdb никак не обойтись. Кроме того, gdb позволяет подключиться к уже работающей программе (через её pid) и заниматься её отладкой «прямо на месте».
Я сейчас не буду подробно описывать pdb, вот замечательная статья Дага Хеллманна (Doug Hellmann): pdb – Interactive Debugger на очень полезном ресурсе Python Module of the Week, а вот её хороший перевод на хабре: pdb – Интерактивный отладчик, выполненный пользователем xa4a.
IPython pdb
Предлагаю сразу поставить IPython и модуль ipdb для него:
IPython (и ipdb, как его часть) предлагает «более лучшую» консоль и, как следствие, более удобную отладку программ: подсветка кода, автодополнение, историю команд, динамическую интроспекцию любых объектов, магические функции, алиасы и многое другое. Полный список улучшений можно посмотреть в документации или прямо из консоли IPython, введя «?» в качестве команды. Всё это помогает при отладке и делает её простой и увлекательной.
Запустить отладку скрипта в ipdb можно несколькими способами:
Эти команды откроют программу в отладчике, дальше можно делать всё, что угодно: ставить брейкпоинты, изучать её работу по шагам или просто запустить программу — отладчик автоматически остановится при возникновении неотловленного исключения.
Но обычно такой вариант чересчур изнурителен: пока доберёшься до нужного места всеми этими «next», «step», да и ставить точку останова («break») руками каждый раз утомительно. Гораздо удобнее в нужном месте программы вставить следующую строку:
И тогда при исполнении этой строки выполнение программы приостановится и будет запущен отладчик, — дальше можно начинать углубляться в изучение программы. По сути, функция «set_trace» — это установка точки останова (breakpoint).
Python Debugger имеет ещё один режим работы, который в некоторых случаях оказывается удобнее фукнции set_trace. Он называется «post mortem»: запуск отладчика с заданным трейсбеком:
В случае возникновения любых неотлавливаемых исключений в функции «some_code» будет вызван отладчик в том месте программы, где произошло исключение.
debug
Интересной заменой функции «set_trace» является модуль debug, который просто импортирует библиотеки ipdb и see (удобная альтернатива функции dir) и запускает отладку. Единственным плюсом модуля является удобство использования, достаточно в любом месте программы вставить строку:
И при выполнении этой строки будет вызван отладчик «ipdb» и импортирован модуль «see».
ipdbplugin
Ещё одна интересная и, на этот раз, полезная библиотека: nose-ipdb. С её помощью можно автоматически запускать отладчик при ошибках (исключениях) или же просто при неверно отработанных тестах (я надеюсь, вы используете nose? =). Для запуска отладчика ipdb при ошибках, достаточно при запуске тестов добавить ключ «—ipdb»:
А для запуска отладчика при некорректно завершившихся тестов нужно добавить ключ «—ipdb-failures»:
Конечно, можно ловить всё и сразу:
Я каждый день использую этот модуль и просто не представляю себе жизни без него.
werkzeug
Потрясающий проект Армина Ронахера (Armin Ronacher), автора фреймворка Flask и вообще одного из крутейших программистов Python называется werkzeug и представляет собой сборник различных утилит для WSGI приложений. Одна из них — клёвый отладчик, который позволяет выводить удобный трейсбек ошибки, а так же запускать консоль Python в соответствующем месте трейсбека прямо на странице браузера:
Использовать его очень просто, достаточно обернуть приложение с помощью соответствующего middleware:
Говорят, что werkzeug умеет отлаживать даже Ajax-запросы, но, к сожалению, я сам лично никогда этого не делал. Буду рад любым комментариям на эту тему.
django-pdb
Ещё один хороший модуль, на этот раз для Django: django-pdb. Он позволяет запускать отладчик при наличии соответствующего GET-параметра в запросе (например: http://127.0.0.1:8000/app/view?ipdb) либо для всех запросов:
Либо вызывать отладчик при возникновении исключений (режим «post-mortem»):
django-extensions
Но гораздо лучше в Django использовать модуль django-extensions, который добавляет очень полезную команду runserver_plus. С помощью этой батарейки можно подружить Django и Werkzeug (см. выше) и начать получать удовольствие от страниц с пятисотой ошибкой =)
Для использования всего этого чуда достаточно запустить девелоперский сервер с помощью команды runserver_plus:
sentry
Отладка программы в девелоперском окружении это, конечно, удобно и хорошо, но самое сложное — локализовать проблему по багрепорту от живого пользователя. Иногда это бывает сложно. Несмотря на все преимущества Python, модуля «телепатии» не существует, и разработчик остаётся один на один со словами пользователя «ничего не работает. 11».
Проект Sentry позволяет сохранять каждую ошибку пользователя с текстом исключения, полным стектрейсом исключения и значениями всех локальных переменных в каждой из функций стектрейса, а так же много другой информации: окружение пользователя (браузер, ОС), все заголовки запроса и вообще всё, что пожелает разработчик.
Одинаковые ошибки группируются, таким образом можно наблюдать за «пульсом» проекта и чинить в первую очередь самые критичные места. Ещё один пример использования sentry — логгирование. Можно просто добавить в спорное место запись в лог сообщения с любыми интересующими разработчика переменными, и всё это окажется в sentry.
Но самый большой плюс в том, что всё это можно (и нужно!) использовать в продакшене.
Ещё один интересный отладчик: PuDB представляет собой консольный дебагер с графическим интерфейсом:
Не буду много о нём писать (честно говоря, я сам активно им не пользовался), предлагаю прочитать короткую заметка на хабре: Удобный отладчик для Python/Django проектов от пользователя int22h или более полный обзор: Отладка Python/Django при помощи PuDB.
Winpdb
Standalone отладчик Python, на этот раз с полноценным графическим интерфейсом: Winpdb:
Его разработчики утверждают, что winpdb в 20 раз быстрее pdb, а так же поддерживает работу с тредами. Очень большой и подробный туториал можно найти на этой странице: code.google.com/p/winpdb/wiki/DebuggingTutorial.
Если честно, я не вижу особого смысла рассматривать каждую из этих IDE, достаточно знать что они есть, что они успешно справляются со своими задачами и вы можете использовать встроенный отладчик прямо из редактора, — это действительно удобно, круто и здорово.
Спасибо всем, кто дочитал и прокомментировал.
Источник