Баннер мобильный (3) Пройти тест

Ищем баги: как отлаживать код на Python

И какие инструменты в этом помогут

Инструкция

28 февраля 2025

Поделиться

Скопировано
Ищем баги: как отлаживать код на Python

Содержание

    Если код не работает как надо — разработчику нужно найти причину ошибки и устранить ее. Этот процесс называется отладкой или дебагом: с помощью специальных инструментов разработчик ищет, в какой момент выполнения кода что-то пошло не так.

    Рассказываем, как устроена отладка кода в Python — одном из самых популярных языков программирования.

    Что такое debug в Python

    Процесс отладки может различаться в зависимости от языков программирования, но общий принцип похож для большинства из них. Разработчик запускает программу и анализирует с помощью специальных инструментов. Например:

    • выполняет каждую команду по отдельности, чтобы увидеть, когда именно код начал работать неверно;
    • останавливает выполнение кода, если наступил момент, когда что-то пошло не так;
    • выводит на экран значения разных переменных, чтобы посмотреть, чему они сейчас равны;
    • отслеживает изменения в переменных и структурах данных;
    • проверяет выполнение выражений, чтобы увидеть, как срабатывает та или иная вычислительная команда.

    Обычно отладка состоит из трассировки — пошагового выполнения кода — и журналирования, то есть вывода информации о состоянии программы. Эти процессы реализуют с помощью специальных утилит, которые называются отладчиками.

    Что такое отладчик и какими они бывают

    Отладчик, или дебаггер — инструмент, с помощью которого код можно выполнять пошагово, анализировать и выводить о нем сведения. Стандартный отладчик Python — часть языка программирования. Другие, более продвинутые, устанавливаются отдельно или входят в состав сред программирования и редакторов кода.

    Вот несколько примеров дебаггеров в Python, которые используют чаще всего.

    pdb (The Python Debugger). Это встроенный отладчик — он не имеет графического интерфейса, а управлять им разработчик может с помощью текстовых команд в консоли. Существует расширенная версия: она называется ipdb, ее нужно скачивать отдельно. У ipdb больше возможностей, например углубленная трассировка, подсветка синтаксиса и другие.

    Отладчики IDE. Внутри сред разработки и редакторов кода обычно есть свои модули для отладки. У них, в отличие от стандартного дебаггера, чаще всего есть графический интерфейс: ими можно пользоваться прямо в окне инструмента для написания кода. Вот несколько примеров IDE и редакторов, где можно отлаживать код на Python:

    • PyCharm — среда программирования, изначально ориентированная на Python. Отладка в PyCharm запускается отдельной командой, для которой есть кнопка в меню. А точку для остановки кода можно поставить мышкой прямо в интерфейсе IDE;
    • Thonny — среда программирования на Python для начинающих. Она довольно простая, но в ней есть все возможности для полноценной отладки кода;
    • VS Code — многофункциональный редактор кода для разных языков программирования. По возможностям он близок к среде программирования — в частности, в нем есть свой отладчик с визуальным интерфейсом. Как и сам редактор, отладчик может поддерживать несколько языков.

    Встроенные команды языка. В самых простых случаях можно вообще не использовать специальный отладчик — а обойтись стандартными возможностями языка. Например, просто добавить в код команды для вывода на экран содержимого переменных, чтобы увидеть, чему они равны в какой-то момент. 

    Такой способ подходит только для простых и коротких программ. Если код обширный, выводить значения всех переменных вручную — долго, трудоемко и не очень эффективно.

    Возможности отладчиков

    Функции и управление разными видами дебаггеров могут различаться в зависимости от инструмента. Но базовая функциональность у большинства из них одинакова или очень похожа — различия в основном касаются каких-то специфических процессов или особенностей реализации. А также — дополнительных возможностей вроде подсветки интерфейса.

    Вот что входит в основные возможности отладчиков для Python.

    Пошаговое выполнение. Это режим выполнения программы, в котором она не срабатывает вся сразу. За один шаг выполняется только одна строчка кода — а затем программа останавливается. Разработчик может проанализировать значения переменных и результаты выполнения операций, а потом отдать команду для следующего шага.

    Breakpoints. Кроме выполнения всей программы по шагам, можно назначить breakpoint — это так называемая точка останова. Python будет выполнять код, пока не дойдет до момента, где поставили эту точку. Затем код перестанет выполняться, а разработчик увидит, в каком состоянии программа находится в данный момент.

    Постмортемная отладка. Так называется отладка, которая происходит уже после падения программы. Например, если она столкнулась с каким-то багом и экстренно завершила работу. Разработчик отдает специальную команду, и отладчик анализирует состояние кода на момент сбоя.

    Этот метод не подходит, если программа в целом работает и успешно завершается, но, например, выдает неверные результаты.

    Асинхронная отладка. Асинхронным называют код, который выполняется не весь сразу, а в качестве реакции на какое-то событие. Например, функция сработает, только если пользователь нажмет на кнопку. Несколько асинхронных функций могут работать в фоне одновременно и не блокировать доступ к основной программе. Отладка такого кода несколько отличается от обычной — поэтому в дебаггере для асинхронных программ предусмотрены отдельные инструменты.

    Навигация по рекурсии. Рекурсией называют процесс, когда какая-то функция вызывает сама себя, но с другими параметрами. В результате образуются вложенные функции. Чтобы отладить рекурсивный процесс, тоже могут понадобиться специальные инструменты — они помогают разработчику не запутаться во вложенных процессах. Например, он сможет видеть, каковы значения переменных внутри каждого запущенного экземпляра функции.

    Как пользоваться разными видами отладки

    Встроенным отладчиком pdb разработчик пользуется через консоль. Делать это можно по-разному. Например, запустить в командной строке отладчик и дать ему на вход файл с кодом:

    python -m pdb script.py

    Или написать в самом участке кода, где подозревается ошибка, специальную команду — а затем запустить программу:

    pdb.set_trace()

    Уже запущенным отладчиком разработчик управляет с помощью коротких команд, которые вводит с клавиатуры. 

    Например, команда n означает next и выполняет весь код до следующей строки. Во вложенные функции отладчик не заходит. А команда s, которая означает step, выполняет строку с заходом в функции, которые вызываются в этой строке.

    Процесс работы с отладчиками IDE и редакторов кода чуть проще интуитивно — у них обычно есть визуальный интерфейс. Как правило разработчик может выделить мышью строку, чтобы назначить в ней точку останова, а для выполнения шагов в меню среды есть кнопки.

    Подробнее узнать, как работать с отладчиком среды, которой вы пользуетесь, можно в ее официальной документации. Кроме руководства по использованию, там можно найти список горячих клавиш, которые упростят работу с инструментом.

    Например, в VS Code режим отладки Python-кода запускается горячей клавишей F5. А в PyCharm для запуска в режиме отладки нужно нажать комбинацию Shift+F9.

    Функции для отладки кода

    Чтобы искать ошибку в коде, разработчик может пользоваться и стандартными возможностями языка. А еще — дополнительными модулями, которые изначально предназначены для других целей, но помогают и в отладке. Рассказываем о некоторых таких функциях — и о том, как они помогают отыскивать баги. 

    pprint(). Это продвинутая версия стандартной функции print(), которая выводит на экран значение выражения в скобках. pprint() отличается от нее тем, что показывает при выводе специальные символы и отличает числа от строк.

    Например, значение переменной a равно 300. Если a — число, pprint(a) выведет просто 300. А если a — строка, функция выведет ‘300’ в кавычках.

    У pprint() есть минус: эта функция может выводить только одно значение за раз. Если нужно вывести несколько значений, можно воспользоваться обычным print() или так называемым выводом в f-строках:

    print(f"{var=}")

    Эта возможность существует специально для отладки. Она позволяет выводить несколько значений за раз, учитывает строки и специальные символы, а еще автоматически добавляет к выводу имя переменной.

    Вывод на экран бывает нужен, чтобы проверить значения переменных в какой-то момент выполнения кода. Например, чтобы быстро узнать, чему равна переменная a, после того как к ней применили функцию.

    locals(). Это функция, которая возвращает значения всех локальных переменных в конкретном участке кода. То есть:

    • если вызвать ее в основной части кода — она вернет все глобальные переменные конкретной программы;
    • если вызвать ее внутри функции — она вернет локальные переменные функции. 

    Результат работы locals() можно вывести на экран с помощью print() или pprint):

    pprint(locals())

    Это также нужно, чтобы проверить, в каком состоянии находятся переменные в конкретный момент выполнения программы.

    Обработка исключений. Технически эта возможность не совсем касается поиска багов. Скорее, она нужна, чтобы возникшая ошибка не привела к падению программы. Разработчик описывает действия, которые программа должна выполнить, если появится та или иная ошибка. Он может «завернуть» в исключение конкретный участок кода с помощью команды try.. except:

    try:
    
    (команды)
    
    except <название ошибки>:
    
    (команды, что делать в случае ошибки)

    Если код внутри блока try выполнится корректно, программа продолжит работать как надо. А если при выполнении кода в try возникнет ошибка — сработают команды, которые находятся в блоке except.

    Например, можно обернуть в try операцию деления одного числа на другое. А в except прописать, что делать, если произойдет деление на ноль и возникнет ошибка ZeroDivisionError. Скажем, можно вывести предупреждение «на ноль делить нельзя».

    Эту конструкцию можно использовать и при дебаггинге. Для этого разработчик оборачивает в нее вызывающий сомнения участок кода и смотрит, срабатывает ли исключение — и какое.

    Команды rich. Модуль rich устанавливается в Python отдельно и содержит разные команды для расширенного вывода информации. Например, он может вывести значения переменных в виде таблицы или списка. В отладке пригодятся минимум две его возможности:

    • rich.inspect() — выводит полные характеристики объекта, который ему передали в скобках. Например, если вызвать inspect() для текстового файла, функция напишет о его размере, кодировке, правах доступа и других параметрах;
    • rich.traceback — структурирует traceback, то есть текстовый отчет о трассировке кода. По умолчанию он выводится как обычное сообщение, которое не слишком удобно читать. А с помощью rich его можно превратить в красивую таблицу — с указанием на строку, где нашлась ошибка, и выводом locals().
    Так выглядит трейсбек, созданный с использованием rich
    Так выглядит трейсбек, созданный с использованием rich. Источник

    Что еще используют для отладки

    Кроме программ-отладчиков и стандартных возможностей языка, для дебаггинга могут применять и сторонние инструменты. Какие именно — зависит от типа ошибки и от вида программы, в которой она возникла. Это справедливо не только для Python, но практически для любой разработки.

    Вот несколько примеров, что могут использовать, чтобы находить ошибки в коде или конфигурациях программ:

    • профилировщики — ПО, которое собирает характеристики работы кода, например время его выполнения или количество выполнений какого-то его участка;
    • логгеры — утилиты, которые записывают логи, то есть журналы событий, происходящих во время работы кода;
    • снифферы — программы, которые перехватывают и анализируют сетевой трафик, если код как-то взаимодействует с сетью;
    • инструменты статического и динамического анализа — программы, которые проверяют код на безопасность и находят в нем уязвимости. 

    Существуют и другие утилиты, которые используют, чтобы повысить качество кода и сделать его безопаснее. Но отладчик — это базовый инструмент проверки, который позволяет найти очевидные ошибки. А продвинутые программы нужны, чтобы отследить более тонкие и неочевидные моменты.

    Краткие выводы

    • Отладка кода — это процесс поиска и локализации ошибок. Разработчик пытается обнаружить, где именно происходит сбой и почему программа не работает как надо.
    • Два главных процесса в отладке — трассировка и журналирование. Трассировка — это пошаговое выполнение кода построчно, а журналирование — запись информации о состоянии разных переменных и функций.
    • Для отладки используют стандартные средства языка программирования и специальные инструменты-отладчики. 
    • В Python есть встроенный отладчик pdb с управлением через консоль. Кроме того, можно пользоваться дебаггерами различных сред программирования и редакторов кода. 

    Инструкция

    Поделиться

    Скопировано
    0 комментариев
    Комментарии