Отладка на Python: способы и фишки
Отладка – один из важных этапов разработки ПО. Есть много определений этого термина: начиная от “процесса нахождения ошибок на этапе разработки и их устранения”, до “убеждения, что алгоритм исполнения программы соответствует ожиданиям”.
Процесс отладки неминуемо следует за кодированием. Крайне рекомендуется проходить отладчиком по всему коду хотя-бы один раз после кодирования, ведь даже в самом простом коде могут быть ошибки. А если код сложнее
def my_function(): pass
то пройти по нему отладчиком даже необходимо и жизненно важно.
На практике я использую отладку на самых разных уровнях: иногда, нужно найти причину вывода отличного от ожидаемого значения в XLS-отчёт, иногда, зайти на сборку в CI-сервере и найти причину упавшего теста, иногда понять почему отчёт в JS-интерфейсе отличается от значений в базе, а иногда найти причину ошибки в одной из системных библиотек.
Для всего этого есть свои инструменты. В браузере – встроенный отладчик и ключевое слово debugger, в системе – gdb, strace, в Python – свои инструменты. Давайте рассмотрим их.
pdb – стандартный отладчик для Python 2/3. Самый простой, но в то же время достаточно мощный чтобы справиться с любой задачей отладки.
Для того чтобы запустить отладчик, достаточно написать в коде
import pdb; pdb.set_trace()
IPython pdb
idpb – расширенный pdb для среды IPython. Поддерживает подсветку синтаксиса и автодополнение. Это, пожалуй, мой основной способ отладки в консоли.
Для того чтобы запустить отладчик, достаточно вызывать в коде
import ipdb; ipdb.set_trace()
PyCharm Remote Debug
Удаленная отладка более репрезентативна чем консольный pdb. Часто используя инструмент с более богатым интерфейсом можно разобраться в проблема быстрее.
Изначально remote debugger поставляемый с PyCharm развивался в пределах среды Eclipse PyDev. Поставляемый с PyCharm компонент pydevd – форк, развиваемый командой JetBrains. Спасибо ребятам, они молодцы.
Как настроить удаленную отладку?
- Убедиться, что у вас PyCharm Professional Edition 🙂
- Настроить Remote Debugger в PyCharm.
- Убедиться что до вас можно достучаться по сети оттуда, где запускается python код. Можно, например, запустить локально netcat-сервер (“netcat -l”), а на хосте с кодом попытаться к этому порту подключиться netcat-клиентом. Если конфигурация сети сложная, всегда можно пробросить порт по SSH.
- Установить на сервер pip-пакет pydevd_pycharm.
- Добавить вызов отладчика в нужное место в коде.
import pydevd_pycharm pydevd_pycharm.settrace('172.17.0.1', port=12345)
Когда Python выполнит этот код, произойдет следующее:
- выполнение программы остановится в этой точке;
- интерпретатор попытается соединиться с PyCharm, слушающим по адресу 172.17.0.1:12345 ;
- при успешном соединении PyCharm отобразит остановленный код.
Ключевой момент: Python-код соединяется с PyCharm-ом, а не наоборот.
VisualStudio Code – PTVSD
Удаленный отладчик VisualStudio Code – PTVSD – гораздо более новый продукт, чем отладчик встроенный в PyCharm. Еще год назад он болел детскими болезнями, наподобие невозможности настроить mapped paths. Однако сейчас, его вполне можно рекомендовать к ежедневному применению. Его большое преимущество перед отладчиком PyCharm – он бесплатен!
Как настроить удаленную отладку?
- Настроить удаленную отладку в VisualStudio Code.
- Убедиться, что ваш ПК может обратиться к порту, открытом на хосте где запускается код. Как и в случае с PyCharm можно пробросить порт по SSH, но использовать нужно не remote port forwarding метод, а local port forwarding, т.к. соединение произойдет из VSCode в Python.
- Установить pip-пакет ptvsd.
- Добавить в отлаживаемый участок кода (например, в вызов какой-либо функции) вызов отладчика.
import ptvsd ptvsd.enable_attach(address=('1.2.3.4', 3000)) ptvsd.wait_for_attach()
Ключевой момент: в отличии от PyCharm-отладчика, отладчик PTVSD сам инициирует сетевое соединение, а не ждет подключения к нему.
arm-отладчика, отладчик PTVSD сам инициирует сетевое соединение, а не ждет подключения к нему.
Заключение
Возможностей для отладки в Python более, чем достаточно и все они имеют свои преимущества и недостатки. Я пользуюсь ipdb и PyCharm + PyDevd в зависимости от ситуации.
- Если мне необходимо отладить код на dev или CI сервере, или нужно отладить код в чужой среде, то я выбираю ipdb, а при его отсутствии pdb. Еще одна причина использовать ipdb – отсутствие автоматической подгрузки дескрипторов.
- Если же мне необходимо полноценно видеть картину происходящего, иметь возможностью по-ходить по коду в среде разработки, то я выбираю отладчик PyCharm PyDevd.
пошаговая отладка в PyCharm
Как запустить пошаговый отладчик? Он вроде как встроенный, но при запуске Debugger, он просто запускает код, и нет пошаговости. Нет вывода значения переменных именно в этот момент выполнения кода.
Отслеживать
1,318 7 7 серебряных знаков 20 20 бронзовых знаков
задан 29 мар 2017 в 16:04
81 2 2 золотых знака 2 2 серебряных знака 3 3 бронзовых знака
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
Поставьте точку останова на том месте, откуда хотите вести отладку:
Пусть есть такой код:
a = [1, 2, 3] b = 1.2 c = 11 d = input() print(a, b, c, d)
Когда вы пошагово дойдете до строки с вводом и выполните её, то у вас должна появится возможность ввести значение в вкладке Console :
Отслеживать
ответ дан 29 мар 2017 в 17:12
2,548 1 1 золотой знак 14 14 серебряных знаков 31 31 бронзовый знак
у меня проблема в том, что при отладке программы я не могу ничего ввести. по ходу программы пользователь вводит данные, я же в процессе отладки ничего не могу ввести
30 мар 2017 в 19:40
@allay, при пошаговом выполнении код с вводом игнорируется?
31 мар 2017 в 14:59
Не знаю в какой ОС Вы работаете, но, к сожалению, с отладкой в PyCharm есть ряд особенностей.
При пошаговом выполнении в *nix системах (в частности, я говорю про Ubuntu 16.04, но думаю, что подобные фокусы есть и в других операционках) возникает проблема с горяими клавишами. Проблема заключается в том, что невозможно использовать их на любой другой раскладке, кроме EN . Среда не реагирует. Связано это с тем, что в списке горячих клавиш ( File -> Settings необходимо выбрать раздел Keymap ) отсутствуют русские комбинации клавиш.
Эту проблему можно решить, если найти соответствующие команды (например, Run. ) и добавить соответствующие русские комбинации:
Такая же ситуация наблюдается и со средой IntelliJ Idea.
Под Windows проблема аналогичная. Но здесь, плюс к этому добавляется неработоспособность команды Step Into . При попытке войти в функцию вываливается ошибка с непонятными логами в виде цифр и букв в непонятных последовательностях. Аналогичная проблема возникает при попытке перейти на следующую строку на условных операторах, но это происходит не всегда. Случаи, когда такое случается, а когда нет, мной выявлены не были. Обойти это недоразуменее можно команду Resume Program , т.е. выполнить до точки останова. Таким образом, можно допрыгнуть до нужного места в коде, в т.ч. внутри функции. Но от такого рода отладки часто устаёшь. Поэтому призываю поставить виртуалку, либо непосредственно *nix систему.
Отладка программ в среде разработки PyCharm
- Перейдите в программе на интересующую Вас строку, начиная с которой будет начала отладка.
- В главном меню выберите Run -> Toggle Line Breakpoint или Run -> Toggle Temporary Line Breakpoint:
- Теперь рядом со строкой появилась красная жирная точка. Это точка останова. Теперь при выполнении программы в режиме отладки среда остановит её в этом месте, и можно будет узнать состояние программы.
- Нажмите правой кнопкой на название файла с программой и выберите Debug:
- Теперь программа запустилась и остановилась на указанной строке. Текущее положение интерпретатора Python в программе отмечается синей строкой. В нижней части экрана появилась вкладка отладки. Там виден список переменных, доступных из данной точки программы.
- Для того, чтобы проследовать вслед за интерпретатором Python вовнутрь функции (на строку 2), в главном меню выберите Run -> Step Into, или нажмите клавишу F7.
- Как и ожидалось, интерпретатор переместил фокус своего внимания на строку 2, вовнутрь функции get_third_from_end() :
- Чтобы сделать шаг вперёд, не заглядывая в используемые функции, используйте команду Run -> Step Over, или клавишу F8:
- Теперь программа переместилась ещё на шаг вперёд. В нижней вкладке при этом появилась новая переменная last , она была создана в строке 2:
- Таким образом можно легко узнавать, что происходит в каждой точке Вашей программы. Это часто необходимо для поиска ошибок, когда Вы не понимаете, почему программа выдаёт некоторый неверный ответ. Удачной отладки!
- ← Предыдущий
- Следующий →
На базе Hugo v0.75.0 • Тема Beautiful Hugo на базе Beautiful Jekyll
Всё, что вы хотели знать об отладке в IntelliJ IDEA
Отладка — это один из самых важных этапов процесса разработки. И дело не только в том, что устранение ошибок занимает, вероятно, большую часть времени: она также особенно необходима при создании бизнес-логики, написании алгоритмов и тестировании кода.
Давайте начнем с основ. Существуют 4 типа точек останова в IntelliJ IDEA.
Точка останова для строки кода
Останавливает приложение в момент достижения им строки кода, содержащей данную точку. Этот тип точки останова может быть добавлен только в выполняемую строку. Если она содержит лямбда-выражение, то вы можете выбрать: либо установить регулярную точку, либо останавливать программу только при вызове лямбда-выражения.
Точка останова для метода
Останавливает приложение при входе/выходе из указанного метода или одной из его реализаций и позволяет проверять условия этого процесса. Данный вид точки останова может сильно замедлить процесс отладки, так что использовать его следует аккуратно и только в случае необходимости.
Точка останова для исключений
Останавливает приложение при выбрасывании Throwable.class или его подклассов.
Точка останова при доступе к полю класса
Останавливает приложение при обращении к указанному полю или внесении в него изменений, что позволяет вам реагировать на взаимодействия с конкретными переменными экземпляра. Например, просмотр того, как инициализируется свойство, или какой метод изменил свое значение.
Для создания точки останова используйте “горячие” клавиши Ctrl + F8. Тип точки останова (для строки кода, для метода или для доступа к полю класса) будет зависеть от того, где вы ее создаете. Для просмотра списка всех точек останова используйте Ctrl + Shift + F8.
Эта возможность сэкономит вам часы работы, а также избавит вас от необходимости искать точки останова и удалять их вручную в том случае, если они останавливают процесс выполнения кода вопреки вашему намерению. Кроме того, данная опция позволяет вам просто их отключить, в результате чего точки не будут останавливать код во время отладки, но при необходимости вы сможете легко включить их повторно. Поэтому вам не нужно запоминать все важные места в проекте и каждый раз создавать и удалять все точки останова.
Suspend (Приостановка)
Определяет, следует ли остановить выполнение приложения в момент достижения точки останова. Имеет два возможных значения: All/Thread. При выборе all происходит приостановка всех потоков, когда какой-либо из них достигает контрольной точки. При выборе thread приостанавливается лишь один поток, достигший этой точки.
Condition (Условие)
Эта опция позволяет задать условие, подлежащее проверке каждый раз при достижении точки останова. Если условие возвращает значение true, то выполняется заданное действие, в противном же случае контрольная точка пропускается.
В качестве условия вы можете использовать:
- различные инструкции, включающие объявления, циклы, анонимные классы и т. д.;
- this (не используется в статическом контексте), например !(this instanceof User) ;
- проверка логических типов или выражений.
Опции логирования
При достижении точки останова в консоль может быть выведено следующее:
1.Сообщение о достижении точки останова: лог сообщает нам Breakpoint reached at package.User.main(User.java:10) .
2.Трассировка стека для текущего окна Frame. Это удобно, если вы намерены проверить, какие методы были вызваны до момента достижения точки останова.
3.Вычисление выражения и запись результата в консоль: результат произвольного выражения, например «Creating. » или users.size() .
Remove once hit (Удаление точки останова при ее достижении)
Определяет, следует ли удалить точку останова из проекта после того, как она была достигнута.
Disable until hitting the following breakpoint (Отключение точки останова до момента достижения другой точки)
Отключает текущую точку останова до тех пор, пока не будет достигнута заданная точка. Вы также можете решить, отключить ли ее после того, как это произошло, или нет.
Filters (Фильтры)
Эта IDE от JetBrains позволяет также настраивать работу с точками, отфильтровывая классы/экземпляры/методы и выполняя остановку только в нужных вам местах.
В вашем распоряжении следующие типы фильтров:
- Catch class filters (классовые фильтры перехвата). Они останавливают приложение при перехвате исключения в заданных классах.
- Instance filters (фильтры экземпляров класса). Эти фильтры указывают на экземпляры объектов, для которых будет срабатывать точка останова.
- Class filters (фильтры классов). Они задают классы, в которых будет срабатывать точка.
- Caller filters (фильтры вызовов). Данный тип фильтров ограничивает действие точки останова в зависимости от вызова текущего метода. Эта опция вам пригодится, если нужно остановиться на точке только в случае вызова этого метода из заданного метода.
Field access/modification (Доступ к полю класса/изменение поля класса)
- Field access. Используйте эту опцию, чтобы точка останова срабатывала при обращении к полю класса.
- Field modification. Если вы хотите, чтобы точка останова срабатывала при внесении изменений в поле класса, то выбирайте данную опцию.
Pass count (Количество проходов)
Определяет, должна ли сработать точка останова после того, как она была пройдена заданное количество раз. Эту опцию удобно применять для циклов отладки или рекурсивных методов.
Caught/uncaught exception (Обработанное/необработанное исключение)
- Caught exception. Опция предназначена для срабатывания точки останова при условии, что заданное исключение было обработано.
- Uncaught exception. Выберите эту опцию для срабатывания точки останова в том случае, если заданное исключение не было обработано. Так вы сможете выявить причины необработанных исключений.
Лучшие практики использования точек останова
Для логирования отладки используйте точки останова, но не инструкцию System.out.println.
Используйте точки останова для ведения логов вместо добавления в код System.out.print . Это позволит применить более гибкий подход к процессу логирования в приложении, а также избежать написания грязного кода и внесения случайных изменений при выполнении Git-коммитов.
Прибегайте к помощи “горячих” клавиш для добавления точек останова, так вы сэкономите довольно много времени.
Использование “горячих” клавиш открывает прекрасные перспективы более продуктивного программирования. Не забывайте про них.
Вы можете создать группу точек останова, например в том случае, если вам нужно отметить точки для решения какой-либо особой задачи. В диалоговом окне Breakpoints (Ctrl+Shift+F8) выберите сначала точку, которую необходимо добавить в группу, а затем — Move to a group.
Выясните исходную причину критических ошибок.
Точки останова для исключений работают с Throwable.class . Вы можете добавить условие, которое поможет вам останавливать выполнение кода только при выбрасывании Error.class , или вы можете свести всё к MyCustomException.class .
Не используйте точки останова для метода без необходимости.
Эти точки могут чрезвычайно замедлить выполнение кода, что приведет к значительным потерям времени.
Если в настоящий момент вам не нужна какая-то отдельная точка, то не удаляйте ее полностью, а просто отключите. Это позволит сэкономить время в будущем, когда вам понадобится протестировать такой же блок кода, поскольку отпадет необходимость искать ее в огромном проекте, и вы просто включите ее повторно.
Это поможет вам вспомнить, почему вам нужна именно эта точка из числа многих других.
Пошаговое выполнение программы
Степпинг (stepping)— это пошаговое выполнение программы.
Когда выполнение кода останавливается на вашей точке, вы можете передвигаться по нему с помощью разных типов шагов. Ниже представлена панель шагов.
Рассмотрим каждый из них подробнее.
Step over (F8) — Шаг с обходом
Данная команда позволяет перешагнуть через текущую строку кода и перейти к следующей. Реализация методов пропускается, и вы переходите к следующей строке текущего метода.
Step into (F7) — Шаг с заходом
Благодаря этому шагу вы переходите внутрь метода для просмотра его кода. Эта опция подходит для тех случаев, когда вы не уверены, что метод возвращает правильное значение.
Step out (Shift + F8) — Шаг с выходом
При помощи этой команды вы выходите из текущего метода и переходите к вызывающему методу.
Run to cursor(Alt + F9) — Выполнение до курсора
Данная команда продолжает выполнение приложения до текущей позиции курсора.
Force step over (Shift+Alt+F8) — Принудительный шаг с обходом
Используя эту команду, вы обходите текущую строку кода и переходите к следующей. Если в вызываемых методах есть точки останова, то они игнорируются.
Drop frame — Возврат к предыдущему фрейму
Эта команда позволяет отменить последний фрейм стека и восстановить предыдущий. Это удобно, например, если вы по ошибке слишком далеко “прошагали” или хотите зайти в функцию, где пропустили важный блок кода.
Resume program (Ctrl + F9) — Возобновление программы
Эта команда возобновляет выполнение приложения до следующей точки останова.
Окно инструментов отладки
Когда вы начинаете отладку, перед вами открывается соответствующее окно инструментов (Debug). Оно используется для контроля за сеансом отладки, отображением и анализом данных программы, а также для выполнения различных действий данного процесса.
В этом окне вы можете видеть созданные объекты, свойства, исключения, значения и т. д. Данная опция удобна для тех случаев, когда вам нужно: 1) убедиться в том, что все свойства инициализированы правильно; 2) уточнить, какие параметры получил метод; 3) посмотреть на трассировку стека исключений.
Лучшие практики пошагового выполнения программы
Step Into (шаг с заходом) применим даже для методов из внешних библиотек.
Иногда внешние библиотеки также могут содержать ошибки. Отладка внешней библиотеки может помочь вам обнаружить неверный код и сообщить о нем ее разработчикам. Или может возникнуть другая проблема. Например, если метод из внешней библиотеки возвращает неожиданное значение, войдите в него для выяснения причины подобного поведения. Возможно, это произошло из-за ошибки в методе объекта equals/hashcode и т. д. или по причине переопределения некоторых классов данной библиотеки в вашем проекте.
Используйте Show Execution Point (Отображение точки выполнения)
Если вы потеряли место, где остановилось выполнение кода, используйте Show Execution Point (Alt + F10) для перехода к достигнутой точке останова.
Иногда причина неожиданного поведения может затаиться там, где у вас нет точек останова. Обратитесь к стеку вызовов и посмотрите, какие методы были выполнены. Это поможет вам найти среди них ошибочный. Кроме того, если вы перейдете к другому методу через стек вызовов, вы сможете увидеть предварительно полученные им параметры.
Вычисление выражений
IntelliJ IDEA также предоставляет возможность вычислять выражения в точке останова. Это удобный способ посмотреть, как поведет себя метод с другими значениями.
Для вычисления выражения используйте клавиши Alt + F8 или кнопку Evaluate.
Лучшие практики вычисления выражений
Если вам необходимо протестировать метод с разными значениями, не нужно создавать объекты вручную и перезапускать приложение. Можете просто вычислить эти значения в имеющемся методе. Это поможет сэкономить время, а также увидеть все свойства возвращаемого объекта.
Вычислитель выражений может выполнять все.
IntelliJ IDEA позволяет вам вычислять не только локальные, но и различные внешние методы или методы java.* . Вычислитель выражений способен даже выполнять методы, отправляющие запрос к другому сервису, давая вам возможность просмотреть подробный ответ.
Будьте аккуратнее с потоками данных (Streams).
Если вы уже один раз прочитали поток данных вычислителем выражений, то он считается прочитанным, поэтому при попытке приложения прочитать его еще раз могут возникнуть ошибки.
Отладка иногда является весьма раздражающим и длительным, но при этом необходимым процессом в работе каждого разработчика. И IntelliJ IDEA предоставляет возможности и опции для того, чтобы сделать ее более удобной, простой и эффективной. Можно любить или не любить процесс отладки, но это не меняет то обстоятельство, что он является значимым этапом разработки.
Напоследок поделюсь самым важным практическим советом:
Если вы истинный разработчик, то забудьте о кнопке Run (Запуск) и используйте только Debug.
- Приключения аналитика в стране кода: пробуждение силы
- Школа ленивого разработчика: ускоренный курс по созданию фрагментов кода в VS Code
- 2 черты отличных программистов