Эффективная отладка с помощью оператора Assert Python

Вы программист? Если это так, отладка является важным навыком, независимо от языка, на котором вы программируете. В этой статье вы узнаете, как использовать оператор assert в Python для эффективной отладки.

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

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

Давай начнем!

Как использовать оператор Assert в Python

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

Синтаксис оператора Assert

Начнем с синтаксиса использования оператора assert в Python:

assert expression, message

Здесь,

  • выражение — любое допустимое выражение Python для оценки. Это может быть условие значения переменной, значение истинности переменной, возвращаемое значение из функции и многое другое.
  • Пока выражение оценивается как True, оператор assert не выдает ошибку и ничего не возвращает. Это указывает на то, что программа работает должным образом.
  • Если выражение больше не равно True, возникает исключение AssertionError.
  • message — необязательная строка. Вы можете указать сообщение, которое будет отображаться в трассировке всякий раз, когда возникает исключение AssertionError.

Далее давайте приступим к кодированию нескольких примеров, в которых оператор assert может помочь нам написать более чистый и безошибочный код.

Вы можете найти примеры кода, используемые в этом руководстве, в этом GitHub gist.

Примеры оператора Assert в Python

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

Чтобы убедиться, что вы случайно не установили переменную скидки в значение, вы можете добавить утверждение. Выражение для оценки: скидка <= max_discount.

>>> max_discount = 50
>>> discount = 20
>>> assert discount <= max_discount

Здесь скидка (20) меньше, чем max_discount (50). Таким образом, оператор assert не выдает никаких ошибок.

Исключение AssertionError

Если для переменной скидки задано значение больше, чем max_discount, возникает исключение AssertionError.

>>> discount = 75
>>> assert discount <= max_discount
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

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

Давайте также воспользуемся строкой сообщения, которая дает более описательную диагностическую информацию. В оператор assert давайте добавим f-строку Python, которая также содержит значения Discount и max_discount.

>>> assert discount <= max_discount, f"discount should be at most {max_discount}; got discount = {discount}"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: discount should be at most 50; got discount = 75

Как видно из выходной ячейки выше, исключение AssertionError теперь включает значения переменных Discount и max_discount.

Отладка и тестирование функций Python с помощью Assert

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

Возьмем пример. Предположим, в классе проводится тест, и учащимся предоставляется возможность ответить на дополнительный вопрос. Любой учащийся, который ответит на дополнительный вопрос, получит 10 дополнительных баллов за тест. 😄

Рассмотрим следующую функцию get_final_score:

  • Он принимает текущий счет, счет и логический бонус.
  • Если учащийся ответил на бонусный вопрос, логический бонус равен True, и он получает на 10 баллов больше, чем его текущий балл.
  • Затем функция возвращает окончательный результат.
def get_final_score(score,bonus):
    if bonus:
        score += 10
    return score

Сделаем несколько вызовов функции. Мы видим, что для оценок 34 и 40 с бонусом, установленным на True и False, окончательные оценки равны 44 и 40 соответственно.

print(get_final_score(34,True))
# 44
print(get_final_score(40,False))
# 40

Однако максимальное количество баллов за тест равно, скажем, 50. Таким образом, если учащийся набрал 49 баллов, а также ответил на бонусный вопрос, функция get_final_score с радостью подсчитает окончательную оценку, равную 59.

print(get_final_score(49,True))
# 59

Технически это возможно. Но допустим, что студент не может набрать больше максимально возможных баллов за тест. 🙂

Итак, давайте инициализируем переменную max_score. И зафиксируйте результат, возвращенный функцией, в переменную final_score.

Затем мы добавляем утверждение, которое проверяет, меньше ли final_score, чем max_score.

def get_final_score(score,bonus):
    if bonus:
        score += 10
    return score

final_score = get_final_score(47,True)
max_score = 50

assert final_score <= max_score

Теперь мы получаем исключение AssertionError для вызова функции get_final_score(47,True):

Traceback (most recent call last):
  File "main.py", line 17, in <module>
    assert final_score <= max_score
AssertionError

Теперь мы добавляем описательную f-строку в оператор assert Python:

assert final_score <= max_score,f"final_score should be at most {max_score}; got {final_score}"
Traceback (most recent call last):
  File "main.py", line 17, in <module>
    assert final_score <= max_score,f"final_score should be at most {max_score}; got {final_score}"
AssertionError: final_score should be at most 50; got 57

Изменение функции

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

  • Функция get_final_score также принимает max_score в качестве параметра.
  • Мы проверяем, является ли бонус True. Если True, мы добавляем 10 баллов к переменной score.
  • Затем мы проверяем, больше ли оценка, чем max_score. Если это так, мы возвращаем max_score.
  • В противном случае мы возвращаем счет.

Теперь мы добились того, что окончательный счет всегда меньше или равен max_score.

def get_final_score(score,bonus,max_score):
    if bonus:
        score += 10
    if score > max_score:
        return max_score
    return score

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

Примечание об исключении AssertionError

Хотя исключение AssertionError возникает, когда выражение оценивается как False, мы должны помнить, что такие ошибки нельзя обрабатывать как исключения. Это означает, что мы не должны делать что-то вроде этого:

try:
    <doing this>
except AssertionError:
    <do this>

В предыдущем примере с get_final_score мы использовали утверждение, чтобы проверить, меньше ли final_score, чем max_score. Затем мы изменили определение функции таким образом, чтобы не было ошибок утверждения.

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

Подводя итог, вы должны использовать утверждение Python для эффективной отладки и не обрабатывать AssertionErrors как исключения.

Заключение

Это руководство помогло вам понять, как использовать оператор assert в Python. Вот краткое изложение того, что вы узнали:

  • Утверждения Python (утверждения) принимают форму выражения утверждения. Это проверяет, истинно ли выражение. Если он не оценивается как True, возникает исключение AssertionError.
  • Вы также можете использовать assert с выражением утверждения синтаксиса, сообщением. Это будет распечатывать строку сообщения всякий раз, когда возникает исключение AssertionError.
  • Вы должны помнить, что не следует реализовывать обработку исключений для обработки ошибок утверждений. И используйте утверждения как полезный инструмент отладки для проверки работоспособности вашего кода.

Как разработчик, утверждения помогают вам при отладке. Чтобы убедиться, что все отдельные компоненты (модули) проекта работают должным образом, вы можете научиться писать модульные тесты на Python.

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