Дебаггер в PyCharm

Содержание:

  1. Основы отладки
  2. Упрощаем себе жизнь

Теория

Основы отладки (Debugging)

Что такое отладка?

Tip

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

PyCharm мы настраивали в 01.03 - Подготовка окружения, а чаще всего дебажить придётся тесты из 04.02 - Основы Pytest.

Основные понятия дебаггера:

Точки остановки (Breakpoints)

Tip

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

Info

Установка в PyCharm: Чтобы установить точку остановки, кликните левой кнопкой мыши в серой области слева от номера строки в редакторе кода. Появится красная точка. Чтобы удалить точку останова, кликните по ней еще раз


Запуск Дебагера

Note

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

  • Чтобы запустить программу из точки входа, такой как метод main(), файл**,** или тест, нажмите значок Run в области возле точки входа и выберите Debug

  • Так же можно запустить отладку в виджете Run (нажмите Debug или используйте сочетание клавиш Shift+F9)

Приостановка/Возобновление сеанса отладки

Tip

Во время сеанса отладки вы можете приостанавливать выполнение программы и возобновлять его позже:

  • Приостановка программы:

    Нажмите кнопку Pause (Pause Program) на панели инструментов отладки. Это остановит выполнение программы в текущем состоянии.

  • Возобновление программы:

    Нажмите кнопку Resume (Resume Program), чтобы продолжить выполнение программы с того места, где она была приостановлена.

Terminate a debugger session

  • Кликните в меню дебагера следующую кнопку

Note

Хорошо давайте уже попробуем подебажить Возьмем следующий код:

def calculate_sum(a, b):
    result = a + b  # Точка остановки здесь
    return result
 
x = 5
y = 10
total = calculate_sum(x, y)
print(total)

Note

Поставим точку остановки на строке, где у нас result и запустим программу в режиме дебагинга

Tip

Что тут у нас произошло:

  1. Программа выполнялась себе спокойно, пока не наткнулась на брейкпоинт
  2. Строка, на которой остановилась программа, еще не исполнялась. Мы можем видеть объекты, которые сейчас есть на момент перед выполнением этой строки
  3. Возобновив программу - оно продолжит свое выполнение, пока не выполнится/упадет/наткнется на следующий брейк поинт

Question

Зачем нам это надо?

Можно выводить все принтами, но нам их надо написать, потом их надо стереть… Намного удобнее смотреть состояние и состав объектов на текущий момент.

Warning

Кстати значение переменной можно изменить, кликаем правой кнопкой мыши и делаем как показано на скриншоте:


🧪Практическое задание:

Example

  1. Запустить все так же
  2. Попробовать поставить брейк поинт как на второй, так и на третьей строке (result). Запустить с отладкой и посмотреть, как отладчик “споткнется” об следующий брейкпоинт

Пошаговое выполнение (Stepping): Переход к следующей строке кода (Step Over, Step Into, Step Out)

Tip

Пошаговая отладка (stepping) — это процесс контроля выполнения программы шаг за шагом.

Note

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

Кнопки пошаговой отладки расположены на панели инструментов окна Debug.

Info

Наведитесь на каждую из них - появится тултип с названием.

Step Over (Шаг через):

Tip

Выполняет текущую строку кода и переходит к следующей.

Warning

Важно: если текущая строка содержит вызов функции или метода, эта функция/метод будет выполнена полностью, но дебаггер не зайдет внутрь нее. Вы перейдете к следующей строке после вызова функции/метода

def inner_function(x):
    return x * 2
 
def outer_function(a):
    b = inner_function(a + 1)  # Step Over здесь
    c = b * 3                # После Step Over выполнение будет здесь
    return c
 
result = outer_function(5)
print(result)

Note

Если установить брейкпоинт на строке b = inner_function(a + 1) и нажать F8 (Step Over), функция inner_function будет выполнена, и значение b будет вычислено, но вы не увидите выполнение внутри inner_function. Выполнение сразу перейдет на строку c = b * 3

Однако если поставить брейкпоинт еще и на 2й строке (return x * 2 ), то Step Over дойдет до этого брейкпоинта внутри метода

  • Force Step Over (Shift + Alt + F8): Игнорирует все брейкпоинты внутри вызываемой функции

🧪Практическое задание:

Example

  1. Повторить полностью пример из урока. Пройти всю программу при помощи Step Over, останавливаясь на каждом шаге и смотря что происходит в дебаггере
  2. Повторить тоже самое, но уже установив еще 1 брейкпоинт на 2й строке в методе inner_function

Step Into (Шаг внутрь):

Info

Если текущая строка содержит вызов функции или метода, Step Into “заходит” внутрь этой функции/метода и останавливается на первой исполняемой строке внутри нее

  • Пример (используем предыдущий код):

Если установить брейкпоинт на строке b = inner_function(a + 1) (5 строка) и нажать F7 (Step Into), дебаггер перейдет внутрь функции inner_function и остановится на строке return x * 2

  • Smart Step Into (Shift + F7): Если в строке несколько вызовов функций/методов, PyCharm предложит вам выбрать, в какую именно функцию/метод нужно “войти”
def func1(x): return x + 1
def func2(x): return x * 2
def func3(x): return x**2
 
result = func1(func2(func3(2))) # Тут несколько вызовов
 
print(result)

Info

Если поставить брейкпоинт на строке с result (5-я строка) и нажать Shift + F7, то PyCharm предложит выбрать в какую из функций зайти

🧪Практическое задание:

Example

  1. Вы верно угадали 🙂 Повторить все что написано было выше

Step Into My Code (Шаг внутрь моего кода):

Note

Эту команду используем при работе с кодом, который использует сторонние библиотеки или фреймворки. Step Into My Code позволяет “войти” только в ваш собственный код (код проекта), игнорируя код библиотек. Это помогает сосредоточиться на отладке именно вашего кода и избежать ненужного просмотра внутренностей библиотек. PyCharm определяет “ваш код” на основе настроек проекта и исключений, которые можно задать в настройках отладчика

  • Пример:
import requests  # Сторонняя библиотека
 
def my_function(url):
    response = requests.get(url)  # Step Into My Code здесь
    if response.status_code == 200:
        return response.text
    else:
        return "Error"
 
url = "https://www.example.com"
content = my_function(url)
print(content)

Info

Если установить брейкпоинт на строке response = requests.get(url) (4-я строка кода) и нажать Step Into My Code, дебаггер не зайдет внутрь функции requests.get(). Он перейдет к следующей строке в функции my_function. Если бы мы использовали обычный Step Into (F7), мы бы попали во внутренности библиотеки requests

🧪Практическое задание:

Example

Повторить то, что описано выше

  1. С Step Into My Code дабы избежать проваливание внутрь библиотеки реквестс
  2. С Step Into - убедиться, что провалились внутрь…

Step Out (Шаг наружу):

Info

Если вы находитесь внутри функции/метода, Step Out выполнит оставшийся код этой функции/метода и вернет вас к строке, следующей за вызовом этой функции/метода в вызывающем коде.

  • Пример:
def inner_function(x):
    return x * 2  # Step Out здесь
 
def outer_function(a):
    b = inner_function(a + 1)  # Step Into здесь
    c = b * 3
    return c
 
result = outer_function(5)
print(result)

Info

Если вы находитесь внутри функции inner_function (после использования Step Into) и нажмете Shift+F8 (Step Out), выполнение inner_function завершится, и вы вернетесь в функцию outer_function на строку c = b * 3

🧪Практическое задание:

Example

  1. Да, все верно, повторить то, что выше)

Run to Cursor (Выполнить до курсора) (Alt + F9)

Tip

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

import requests  # Сторонняя библиотека
 
def my_function(url):
    response = requests.get(url)  # брейкпоинт сюда
    if response.status_code == 200:
        return response.text
    else:
        return "Error"
 
url = "https://www.example.com"
content = my_function(url)
i = "i'm here"
print(content)

Tip

Установим брейкпоинт my_function (3-я строка), и запустим отладчик. Установим курсор на i = "i'm here" (12 строка) и запустим Run to Cursor


🧪Практическое задание:

Example

Упражнение 1: Step Over и Step Into

def process_data(data):
    processed_data = transform_data(data)
    result = calculate_result(processed_data)
    return result
 
def transform_data(data):
    return [x * 2 for x in data]
 
def calculate_result(data):
    return sum(data)
 
data = [1, 2, 3]
final_result = process_data(data)
print(final_result)
  1. Установите брейкпоинт на строке processed_data = transform_data(data)
  2. Запустите отладку
  3. Используйте Step Over (F8), чтобы выполнить строку и перейти к следующей
  4. Снова установите брейпоинт на ту же строку
  5. Запустите отладку
  6. Используйте Step Into (F7), чтобы “войти” внутрь функции transform_data
  7. Используйте Step Over внутри transform_data, чтобы выполнить каждую строку
  8. Используйте Step Out (Shift+F8), чтобы вернуться в функцию process_data

Упражнение 2: Step Out и просмотр переменных

def inner(a, b):
    c = a + b
    d = c * 2 # Поставьте тут точку останова
    return d
 
def outer(x):
    y = 10
    z = inner(x, y)
    return z
 
result = outer(5)
print(result)
  1. Установите точку останова на строке d = c * 2
  2. Запустите отладку
  3. Посмотрите значения a, b, c в окне Variables
  4. Используйте Step Out
  5. Посмотрите значения x, y, z в окне Variables

Упражнение 3: Smart Step Into

def a(x): print("a"); return x + 1
def b(x): print("b"); return x * 2
def c(x): print("c"); return x ** 2
 
result = a(b(c(2))) # Поставьте тут точку останова
print(result)
  1. Установите точку останова на строке result = a(b(c(2))).
  2. Запустите отладку.
  3. Нажмите Shift + Alt + F7 (Smart Step Into).
  4. Выберите функцию c для входа.
  5. Повторите шаги 3 и 4, выбирая функции b и a по очереди.

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


Выходим за основы и упрощаем себе жизнь до уровня бизнес-комфорт++

Example

Посмотреть видео, начать использовать в ближайших практиках

https://www.youtube.com/watch?v=mRxJHzXzVec



⬅️ Назад: 04.03 - Основы Requests Модуль: 04 - MOC