Поиск ошибок в программе питон
Высокая стоимость ошибок в программных продуктах предъявляет повышенные
требования к качеству кода. Каким критериям должен соответствовать хороший код?
Отсутствие ошибок, расширяемость, поддерживаемость, читаемость и наличие документации. Недостаточное внимание к любому из этих критериев может привести к появлению новых ошибок или снизить вероятность обнаружения уже существующих. Небрежно написанный или чересчур запутанный код, отсутствие документации напрямую влияют на время исправления найденного бага, ведь разработчику приходится заново вникать в код. Даже такие, казалось бы, незначительные вещи как неправильные имена переменных или отсутствие форматирования могут сильно влиять на читаемость и понимание кода.
Командная работа над проектом еще больше повышает требования к качеству кода, поэтому важным условием продуктивной работы команды становится описание формальных требований к написанию кода. Это могут быть соглашения, принятые в языке программирования, на котором ведется разработка, или собственное (внутрикорпоративное) руководство по стилю. Выработанные требования к оформлению кода не исключают появления "разночтений" среди разработчиков и временных затрат на их обсуждение. Кроме этого, соблюдение выработанных требований ложится на плечи программистов в виде дополнительной нагрузки. Все это привело к появлению инструментов для проверки кода на наличие стилистических и логических ошибок. О таких инструментах для языка программирования Python мы и поговорим в этой статье.
Анализаторы и автоматическое форматирование кода
Весь инструментарий, доступный разработчикам Python, можно условно разделить на две группы по способу реагирования на ошибки. Первая группа сообщает о найденных ошибках, перекладывая задачу по их исправлению на программиста. Вторая — предлагает пользователю вариант исправленного кода или автоматически вносит изменения.
И первая, и вторая группы включают в себя как простые утилиты командной строки для решения узкоспециализированных задач (например, проверка docstring или сортировка импортов), так и богатые по возможностям библиотеки, объединяющие в себе более простые утилиты. Средства анализа кода из первой группы принято называть линтерами (linter). Название происходит от lint — статического анализатора для языка программирования Си и со временем ставшего нарицательным. Программы второй группы называют форматировщиками (formatter).
Даже при поверхностном сравнении этих групп видны особенности работы с ними. При применении линтеров программисту, во-первых, необходимо писать код с оглядкой, дабы позже не исправлять найденные ошибки. И во вторых, принимать решение по поводу обнаруженных ошибок — какие требуют исправления, а какие можно проигнорировать. Форматировщики, напротив, автоматизируют процесс исправления ошибок, оставляя программисту возможность осуществлять контроль.
Список рассматриваемых инструментов для анализа кода Python
Часть 1
Часть 2
Соглашения принятые в статье и общие замечания
Прежде чем приступить к обзору программ, мы хотели бы обратить ваше внимание на несколько важных моментов.
Версия Python: во всех примерах, приведенных в статье, будет использоваться третья версия языка программирования Python.
Установка всех программ в обзоре практически однотипна и сводится к использованию пакетного менеджера pip.
Некоторые из библиотек имеют готовые бинарные пакеты в репозиториях дистрибутивов linux или возможность установки с использованием git. Тем не менее для большей определенности и возможности повторения примеров из статьи, установка будет производится с помощью pip.
Об ошибках: стоит упомянуть, что говоря об ошибках, обнаруживаемых анализаторами кода, как правило, имеют в виду два типа ошибок. К первому относятся ошибки стиля (неправильные отступы, длинные строки), ко второму — ошибки в логике программы и ошибки синтаксиса языка программирования (опечатки при написании названий стандартных функций, неиспользуемые импорты, дублирование кода). Существуют и другие виды ошибок, например — оставленные в коде пароли или высокая цикломатическая сложность.
Тестовый скрипт: для примеров использования программ мы создали простенький по содержанию файл example.py. Мы сознательно не стали делать его более разнообразным по наличию в нем ошибок. Во-первых, добавление листингов с выводом некоторых анализаторов в таком случае сильно “раздуло” бы статью. Во-вторых, у нас не было цели детально показать различия в “отлове” тех или иных ошибок для каждой из утилит.
Содержание файла example.py:
В коде допущено несколько ошибок:
- импорт неиспользуемого модуля os,
- импорт не существующего модуля notexistmodule,
- имя функции начинается с заглавной буквы,
- лишние аргументы в определении функции,
- отсутствие self первым аргументом в методе класса,
- неверное форматирование.
Pycodestyle
Pycodestyle — простая консольная утилита для анализа кода Python, а именно для проверки кода на соответствие PEP8. Один из старейших анализаторов кода, до 2016 года носил название pep8, но был переименован по просьбе создателя языка Python Гвидо ван Россума.
Запустим проверку на нашем коде:
Лаконичный вывод показывает нам строки, в которых, по мнению анализатора, есть нарушение соглашений PEP8. Формат вывода прост и содержит только необходимую информацию:
Возможности программы по проверке соглашений ограничены: нет проверок на правильность именования, проверка документации сводится к проверки длины docstring. Тем не менее функционал программы нельзя назвать “спартанским”, он позволяет настроить необходимый уровень проверок и получить различную информацию о результатах анализа. Запуск с ключом --statistics -qq выводит статистику по ошибкам:
Если есть необходимость посмотреть, какие из соглашений PEP8 были нарушены, используйте ключ -- show-pep8. Программа выведет список всех проверок с выдержками из PEP8 для случаев нарушений. При обработке файлов внутри директорий предусмотрена возможность фильтрации по шаблону. Pycodestyle позволяет сохранять настройки поиска в конфигурационных файлах как глобально, так и на уровне проекта.
Pydocstyle
Утилиту pydocstyle мы уже упоминали в статье Работа с документацией в Python: поиск информации и соглашения. Pydocstyle проверяет наличие docstring у модулей, классов, функций и их соответствие официальному соглашению PEP257.
Как мы видим из листинга, программа указала нам на отсутствие документации в определениях функции, методов класса и ошибки оформления в docstring класса. Вывод можно сделать более информативным, если использовать ключи --explain и --source при вызове программы. Функционал pydocstyle практически идентичен описанному выше для pycodestyle, различия касаются лишь названий ключей.
Pyflakes
В отличие от уже рассмотренных инструментов для анализа кода Python pyflakes не делает проверок стиля. Цель этого анализатора кода — поиск логических и синтаксических ошибок. Разработчики pyflakes сделали упор на скорость работы программы, безопасность и простоту. Несмотря на то, что данная утилита не импортирует проверяемый файл, она прекрасно справляется c поиском синтаксических ошибок и делает это быстро. С другой стороны, такой подход сильно сужает область проверок.
Функциональность pyflakes — “нулевая”, все что он умеет делать — это выводить результаты анализа в консоль:
В нашем тестовом скрипте, он нашел только импорт не используемого модуля os. Вы можете самостоятельно поэкспериментировать с запуском программы и передачей ей в качестве параметра командной строки Python файла, содержащего синтаксические ошибки. Данная утилита имеет еще одну особенность — если вы используете обе версии Python, вам придется установить отдельные утилиты для каждой из версий.
Pylint
До сих пор мы рассматривали утилиты, которые проводили проверки на наличие либо стилистических, либо логических ошибок. Следующий в обзоре статический инструмент для анализа кода Python — Pylint, который совместил в себе обе возможности. Этот мощный, гибко настраиваемый инструмент для анализа кода Python отличается большим количеством проверок и разнообразием отчетов. Это один из самых “придирчивых” и “многословных” анализаторов кода. Анализ нашего тестового скрипта выдает весьма обширный отчет, состоящий из списка найденных в ходе анализа недочетов, статистических отчетов, представленных в виде таблиц, и общей оценки кода:
Программа имеет свою внутреннюю маркировку проблемных мест в коде:
[R]efactor — требуется рефакторинг,
[C]onvention — нарушено следование стилистике и соглашениям,
[W]arning — потенциальная ошибка,
[E]rror — ошибка,
[F]atal — ошибка, которая препятствует дальнейшей работе программы.
— Генерация файла настроек (--generate-rcfile). Позволяет не писать конфигурационный файл с нуля. В созданном rcfile содержатся все текущие настройки с подробными комментариями к ним, вам остается только отредактировать его под собственные требования.
— Создание отчетов в формате json (--output-format=json). Полезно, если необходимо сохранение или дальнейшая обработка результатов работы линтера. Вы также можете создать собственный формат вывода данных.
— Параллельный запуск (-j 4). Запуск в нескольких параллельных потоках на многоядерных процессорах сокращает время проверки.
— Система оценки сохраняет последний результат и при последующих запусках показывает изменения, что позволяет количественно оценить прогресс исправлений.
— Плагины — отличная возможность изменять поведение pylint. Их применение может оказаться полезным в случаях, когда pylint неправильно обрабатывает код и есть “ложные” срабатывания, или когда требуется отличный от стандартного формат вывода результатов.
Vulture
Vulture — небольшая утилита для поиска “мертвого” кода в программах Python. Она использует модуль ast стандартной библиотеки и создает абстрактные синтаксические деревья для всех файлов исходного кода в проекте. Далее осуществляется поиск всех объектов, которые были определены, но не используются. Vulture полезно применять для очистки и нахождения ошибок в больших базовых кодах.
Продолжение следует
Во второй части мы продолжим разговор об инструментах для анализа кода Python. Будут рассмотрены линтеры, представляющие собой наборы утилит. Также мы посмотрим, какие программы можно использовать для автоматического форматирования кода.
ФРОО рекомендует:
До конца октября действует промокод backupmaster, который дает скидку 5000 рублей на курс Программирование на Python и 5000 рублей на курс Машинное обучение и анализ данных.
Все допускают ошибки – даже опытные профессиональные разработчики, а Python и IDLE отлично их улавливают. Давайте разберемся, как это работает.
Перевод публикуется с сокращениями, автор оригинальной статьи David Amos.
Выявление ошибок называется дебаггингом, а дебаггер – помогающий понять причину их появления инструмент. Умение находить и исправлять ошибки в коде – важный навык в работе программиста, не пренебрегайте им.
IDLE (Integrated Development and Learning Environment) – кроссплатформенная интегрированная среда разработки и обучения для Python, созданная Гвидо ван Россумом.
Основным интерфейсом отладки в IDLE является специальное окно управления (Debug Control window). Открыть его можно, выбрав в меню интерактивного окна пункт Debug→Debugger.
Примечание: если отладка отсутствует в строке меню, убедитесь, что интерактивное окно находится в фокусе.
Всякий раз, когда окно отладки открыто, интерактивное окно отображает [DEBUG ON].
Обзор окна управления отладкой
Чтобы увидеть работу отладчика, напишем простую программу без ошибок. Введите в редактор следующий код:
Сохраните все, откройте окно отладки и нажмите клавишу F5 – выполнение не завершилось.
Окно отладки будет выглядеть следующим образом:
Расшифруем: код for i in range(1, 4): еще не запущен, а '__main__'.module() сообщает, что в данный момент мы находимся в основном разделе программы, а не в определении функции.
Ниже панели стека находится панель Locals, в которой перечислены непонятные вещи: __annotations__, __builtins__, __doc__ и т. д. – это внутренние системные переменные, которые пока можно игнорировать. По мере выполнения программы переменные, объявленные в коде и отображаемые в этом окне, помогут в отслеживании их значений.
В левом верхнем углу окна расположены пять кнопок: Go, Step, Over, Out и Quit – они управляют перемещением отладчика по коду.
В следующих разделах вы узнаете, что делает каждая из этих кнопок.
Кнопка Step
Нажмите Step и окно отладки будет выглядеть следующим образом:
На этом этапе выполняется line 1 и отладчик останавливается перед выполнением line 2.
Во-вторых – новая переменная i со значением 1 на панели Locals . Цикл for в line 1 создал переменную и присвоил ей это значение.
Продолжайте нажимать кнопку Step, чтобы пройтись по коду строка за строкой, и наблюдайте, что происходит в окне отладчика. Когда доберетесь до строки print(f"i is and j is ") , сможете увидеть вывод, отображаемый в интерактивном окне по одному фрагменту за раз.
Здесь важно, что можно отслеживать растущие значения i и j по мере прохождения цикла for. Это полезная фича поиска источника ошибок в коде. Знание значения каждой переменной в каждой строке кода может помочь точно определить проблемную зону.
Точки останова и кнопка Go
Часто вам известно, что ошибка должна всплыть в определенном куске кода, но неизвестно, где именно. Чтобы не нажимать кнопку Step весь день, установите точку останова, которая скажет отладчику запускать весь код, пока он ее не достигнет.
Точки останова сообщают отладчику, когда следует приостановить выполнение кода, чтобы вы могли взглянуть на текущее состояние программы.
Чтобы установить точку останова, щелкните правой кнопкой мыши (Ctrl для Mac) по строке кода, на которой хотите сделать паузу, и выберите пункт Set Breakpoint – IDLE выделит линию желтым. Чтобы удалить ее, выберите Clear Breakpoint.
Установите точку останова в строке с оператором print(). Окно редактора должно выглядеть так:
Теперь на панели стека информация о выполнении line 3:
На панели Locals мы видим, что переменные i и j имеют значения 1 и 2 соответственно. Нажмем кнопку Go и попросим отладчик запускать код до точки останова или до конца программы. Снова нажмите Go – окно отладки теперь выглядит так:
Over и Out
Кнопка Over работает, как сочетание Step и Go – она перешагивает через функцию или цикл. Другими словами, если вы собираетесь попасть в функцию с помощью отладчика, можно и не запускать код этой функции – кнопка Over приведет непосредственно к результату ее выполнения.
Аналогично если вы уже находитесь внутри функции или цикла – кнопка Out выполняет оставшийся код внутри тела функции или цикла, а затем останавливается.
Взглянем на « глючную » программу.
Следующий код определяет функцию add_underscores(), принимающую в качестве аргумента строковый объект и возвращающую новую строку – копию слова с каждым символом, окруженным подчеркиванием. Например, add_underscores("python") вернет «_p_y_t_h_o_n_» .
Вот неработающий код:
Введите этот код в редактор, сохраните и нажмите F5. Ожидаемый результат – _h_e_l_l_o_, но вместо этого выведется o_.
Если вы нашли, в чем проблема, не исправляйте ее. Наша цель – научиться использовать для этого IDLE.
Рассмотрим 4 этапа поиска бага:
- предположите, где может быть ошибка;
- установите точку останова и проверьте код по строке за раз;
- определите строку и внесите изменения;
- повторяйте шаги 1-3, пока код не заработает.
Шаг 1: Предположение
Сначала вы не сможете точно определить местонахождение ошибки, но обычно проще логически представить, в какой раздел кода смотреть.
Обратите внимание, что программа разделена на два раздела: определение функции add_underscores() и основной блок, определяющий переменную со значением «hello» и выводящий результат.
Посмотрим на основной раздел:
Очевидно, что здесь все хорошо и проблема должна быть в определении функции:
Первая строка создает переменную new_word со значением «_». Промах, проблема находится где-то в теле цикла for.
Шаг 2: точка останова
Определив, где может быть ошибка, установите точку останова в начале цикла for, чтобы проследить за происходящим внутри кода:
Запустим. Выполнение останавливается на строке с определением функции.
Код останавливается перед циклом for в функции add_underscores(). Обратите внимание, что на панели Locals отображаются две локальные переменные – word со значением «hello», и new_word со значением «_»,
Переменная i – это счетчик для цикла for, который можно использовать, чтобы отслеживать активную на данный момент итерацию.
Это неправильно т. к. сначала в new_word было значение «_», на второй итерации цикла for в ней должно быть «_h_». Если нажать Step еще несколько раз, то увидим, что в new_word попадает значение e_, затем l_ и так далее.
Шаг 3: Определение ошибки и исправление
Как мы уже выяснили – на каждой итерации цикла new_word перезаписывается следующим символом в строке «hello» и подчеркиванием. Поскольку внутри цикла есть только одна строка кода, проблема должна быть именно там:
Код указывает Python получить следующий символ word, прикрепить подчеркивание и назначить новую строку переменной new_word. Это именно то неверное поведение, которое мы наблюдали.
Примечание: Если бы вы закрыли отладчик, не нажав кнопку Quit, при повторном открытии окна отладки могла появиться ошибка:
You can only toggle the debugger when idle
Всегда нажимайте кнопку Go или Quit, когда заканчиваете отладку, иначе могут возникнуть проблемы с ее повторным запуском.
Шаг 4: повторение шагов 1-3, пока ошибка не исчезнет
Сохраните изменения в программе и запустите ее снова. В окне отладки нажмите кнопку Go, чтобы выполнить код до точки останова. Понажимайте Step несколько раз и смотрите, что происходит с переменной new_word на каждой итерации – все работает, как положено. Иногда необходимо повторять этот процесс несколько раз, прежде чем исправится ошибка.
Альтернативные способы поиска ошибок
Использование отладчика может быть сложным и трудоемким, но это самый надежный способ найти ошибки в коде. Однако отладчики не всегда есть в наличии. В подобных ситуациях можно использовать print debugging для поиска ошибок в коде. PD задействует функцию print() для отображения в консоли текста, указывающего место выполнения программы и состояние переменных.
Например, вместо отладки предыдущего примера можно добавить следующую строку в конец цикла for:
Измененный код будет выглядеть следующим образом:
Вывод должен выглядеть так:
PD работает, но имеет несколько недостатков по сравнению с отладкой дебаггером. Вы должны запускать всю программу каждый раз, когда хотите проверить значения переменных, а также помнить про удаление вызовов функций print().
Один из способов улучшить наш цикл – перебирать символы в word:
Заключение
Теперь вы знаете все об отладке с помощью DLE. Вы можете использовать этот принцип с различными дебагерами.
Анализ кода в Python может быть трудной темой, но очень полезной в тех случаях, когда вам нужно повысить производительность вашей программы. Существует несколько анализаторов кода для Python, которые вы можете использовать для проверки своего кода и выяснить, соответствует ли он стандартам. Самым популярным можно назвать pylint. Он очень удобен в настойках и подключениях. Он также проверяет ваш код на соответствие с PEP8, официальным руководством по стилю ядра Python, а также ищет программные ошибки. Обратите внимание на то, что pylint проверяет ваш код на большую часть стандартов PEP8, но не на все. Также мы уделим наше внимание тому, чтобы научиться работать с другим анализатором кода, а именно pyflakes.
Начнем с pylint
Пакет pylint не входит в Python, так что вам нужно будет посетить PyPI (Python Package Index), или непосредственно сайт пакета для загрузки. Вы можете использовать следующую команду, которая сделает всю работу за вас:
Если все идет по плану, то pylint установится, и мы сможем пойти дальше.
Анализ вашего кода
После установки pylint вы можете запустить его в командной строке, без каких либо аргументов, что бы увидеть, какие опции он принимает. Если это не сработало, можете прописать полный путь, вот так:
Теперь нам нужен какой-нибудь код для анализа. Вот часть кода, которая содержит четыре ошибки. Сохраните её в файле под названием crummy_code.py:
Можете увидеть ошибки не запуская код? Давайте посмотрим, может ли pylint найти их!
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
После запуска этой команды вы увидите большую выдачу на вашем экране. Вот частичный пример:
Давайте немного притормозим и разберемся. Сначала нам нужно понять, что означают буквы:
- С – конвенция (convention)
- R – рефакторинг (refactor)
- W – предупреждение (warning)
- E – ошибка (error)
Давайте запустим новый код с pylint и посмотрим, насколько успешно мы провели работу. Для краткости, мы еще раз рассмотрим первую часть:
Как мы видим, это очень помогло. Если мы добавим docstrings, мы можем снизить количество ошибок вдвое. Теперь мы готовы перейти к pyflakes!
Работаем с pyflakes
Проект pyflakes это часть чего-то, что называется Divmod Project. Pyflakes на самом деле не выполняет проверяемый код также, как и pylint. Вы можете установить pyflakes при помощи pip, easy_install, или из другого источника.
Данный сервис может предложить Вам персональные условия при заказе классов на посты и фото в Одноклассники. Приобретайте необходимый ресурс не только со скидками, но и с возможностью подобрать наилучшее качество и скорость поступления.
Мы начнем с запуска pyflakes в изначальной версии той же части кода, которую мы использовали для проверки pylint. Вот и он:
Как мы отмечали в предыдущем разделе, в этом поломанном коде четыре ошибки, три из которых препятствуют работе программы. Давайте посмотрим, что же pyflakes может найти. Попытайтесь запустить данную команду и на выходе вы должны получить следующее:
Несмотря на суперски быструю скорость возврата выдачи, pyflakes не нашел все ошибки. Вызов метода getWeight передает слишком много аргументов, также метод getWeight сам по себе определен некорректно, так как у него нет аргумента self. Что-же, вы, собственно, можете называть первый аргумент так, как вам угодно, но в конвенции он всегда называется self. Если вы исправили код, оперируя тем, что вам сказал pyflakes, код не заработает, несмотря на это.
Подведем итоги
Следующим шагом должна быть попытка запуска pylint и pyflakes в вашем собственном коде, либо же в пакете Python, вроде SQLAlchemy, после чего следует изучить полученные в выдаче данные. Вы можете многое узнать о своем коде, используя данные инструменты. pylint интегрирован с Wingware, Editra, и PyDev. Некоторые предупреждения pylint могут показаться вам раздражительными, или не особо уместными. Существует несколько способов избавиться от таких моментов, как предупреждения об устаревании, через опции командной строки. Вы также можете использовать -generate-rcfile для создания примера файла config, который поможет вам контролировать работу pylint. Обратите внимание на то, что pylint и pyflakes не импортируют ваш код, так что вам не нужно беспокоиться о нежелательных побочных эффектах.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
Каждый хотел бы облегчить процесс дебаггинга и избавиться от головной боли. Решаем эту проблему с помощью инструментов для отслеживания выполнения кода на Python.
Перевод публикуется с сокращениями, автор оригинальной статьи Khuyen Tran.
Мотивация
Вы наверняка видели вывод ошибок наподобие показанного ниже:
и хотели, чтобы его было немного легче понять:
Возможно, вам даже захочется визуализировать, какие строки кода выполняются и сколько раз:
Если так, статья даст необходимые инструменты, чтобы достичь цели:
- Loguru – вывод сработавших исключений;
- snoop – печать строк кода, выполняемого в функции;
- heartrate – визуализация выполнения программы в режиме реального времени.
Все, что нужно для использования этих инструментов – одна строка кода!
Loguru
Loguru – это библиотека, которая сделает общение с системой журналов в Python приятнее. Она предоставляет много интересных функций, но одна из них заслуживает отдельного внимания – возможность отлавливать неожиданные ошибки и отображать, какое значение переменной приводит к сбою кода.
Установить Loguru можно одной командой:
Чтобы понять, чем Loguru может быть вам полезна, представьте, что есть 2 функции – division и divide_numbers, при этом функция divide_numbers сейчас выполняется.
Обратите внимание, что комбинации ([2,1,0], 2) возвращают [(2, 1), (2, 0), (1, 0)]. После выполнения приведенного выше кода мы получим следующую ошибку:
Из выходных данных становится ясно, что возвращающая num1 / num2 строка является местом возникновения ошибки, но непонятно, какие значения num1 и num2 ее вызывают. Это можно легко отследить, добавив декоратор Loguru.catch:
Добавив logger.catch исключения гораздо проще понять: ошибка возникает при делении 2 на 0.
Snoop
Как быть, если в коде нет ошибки, но мы хотим выяснить, что в нем происходит? В этом случае пригодится snoop . Это пакет Python, который выводит на экран строки выполняемого кода вместе со значениями каждой переменной, добавляя только один декоратор.
Чтобы установить snoop, введите следующую команду:
Представим, что у нас есть функция под названием factorial, которая находит факториал целого числа:
Чтобы понять, почему результат factorial(5) равен 20, добавим декоратор snoop в функцию factorial.
В приведенном выше выводе можно просмотреть значения переменных, и какие строки кода выполняются. Теперь легче понять, как работает рекурсия.
Heartrate
Если необходимо визуализировать, какие строки и сколько раз выполняются, попробуйте heartrate.
H eartrate также создан разработчиками snoop. Чтобы его установить, введите команду:
Теперь добавим heartrate.trace(browser=True) в предыдущий код. Это откроет отображающее визуализацию файла окно браузера , в котором была вызвана функция trace():
Диаграммы подсвечивают искомые строки: более длинные полосы означают больше попаданий, а светлые цвета – более свежее изменение.
На приведенной выше иллюстрации мы видим, как выполняется код:
- if x==1 (5 раз)
- return 1 (1 раз)
- return (x * factorial(x-1)) (4 раза)
Вывод имеет смысл, так как начальное значение x равно 5, и функция вызывается повторно до тех пор, пока x не станет равным 1.
Теперь посмотрим, как визуализировать выполнение в режиме реального времени с помощью heartrate . Добавим sleep (0.5) , чтобы программа работала немного медленнее, и увеличим num до 20.
Теперь мы можем в режиме реального времени видеть, какие строки кода выполняются, и сколько раз отработала каждая из них.
Заключение
Мы изучили три инструмента для отслеживания и визуализации выполнения кода в Python. Надеемся, что с ними отладка станет для вас менее болезненной. Поскольку эти инструменты требуют только одной строки кода, почему бы не попробовать их в работе? Удачи в обучении!
Что вы предпринимаете, когда с работой вашей программы что-то идет не так? Допустим, вы пытаетесь открыть файл, но вы ввели неверный путь, или вы хотите узнать информацию у пользователей и они пишут какую-то бессмыслицу. Вы не хотите, чтобы ваша программа крэшилась, по-этому вы выполняете обработку исключений. В Пайтоне, конструкция всегда обернута в то, что называется try/except. В данном разделе мы рассмотрим следующие понятия:
- Базовые типы исключений;
- Обработка исключений при помощи try/except;
- Узнаем, как работает try/except/finally;
- Выясним, как работает оператор else совместно с try/except;
Начнем со знакомства с самыми обычными исключениями, которые вы увидите в Пайтоне. Обратите внимание на то, что ошибка и исключение – два разных слова, описывающие одно и то же, в контексте обработки исключений.
Основные исключения
Вы уже сталкивались со множеством исключений. Ниже изложен список основных встроенных исключений (определение в документации к Пайтону):
- Exception – то, на чем фактически строятся все остальные ошибки;
- AttributeError – возникает, когда ссылка атрибута или присвоение не могут быть выполнены;
- IOError – возникает в том случае, когда операция I/O (такая как оператор вывода, встроенная функция open() или метод объекта-файла) не может быть выполнена, по связанной с I/O причине: «файл не найден», или «диск заполнен», иными словами.
- ImportError – возникает, когда оператор import не может найти определение модуля, или когда оператор не может найти имя файла, который должен быть импортирован;
- IndexError – возникает, когда индекс последовательности находится вне допустимого диапазона;
- KeyError – возникает, когда ключ сопоставления (dictionary key) не найден в наборе существующих ключей;
- KeyboardInterrupt – возникает, когда пользователь нажимает клавишу прерывания(обычно Delete или Ctrl+C);
- NameError – возникает, когда локальное или глобальное имя не найдено;
- OSError – возникает, когда функция получает связанную с системой ошибку;
- SyntaxError — возникает, когда синтаксическая ошибка встречается синтаксическим анализатором;
- TypeError – возникает, когда операция или функция применяется к объекту несоответствующего типа. Связанное значение представляет собой строку, в которой приводятся подробные сведения о несоответствии типов;
- ValueError – возникает, когда встроенная операция или функция получают аргумент, тип которого правильный, но неправильно значение, и ситуация не может описано более точно, как при возникновении IndexError;
- ZeroDivisionError – возникает, когда второй аргумент операции division или modulo равен нулю;
Существует много других исключений, но вы вряд ли будете сталкиваться с ними так же часто. В целом, если вы заинтересованы, вы можете узнать больше о них в документации Пайтон.
Как обрабатывать исключения?
Обработка исключений в Пайтон – это очень просто. Потратим немного времени и напишем несколько примеров, которые их вызовут. Мы начнем с одной из самых элементарных проблем: деление на ноль.
Читайте также: