Отладочные утверждения assert в Python
Инструкция assert — это удобный способ вставить отладочные утверждения в программу. Этот оператор помогает обнаружить проблемы на ранних этапах программы, когда причина ясна, а не позже как побочный эффект какой-либо другой операции.
Инструкция assert будет игнорироваться (не будет выполняться) интерпретатором Python, если запустить его в оптимизированном режиме (опция -O при запуске скрипта Python).
Синтаксис:
Базовая форма инструкции утверждения assert в Python.
assert expression # эквивалентно коду if __debug__: if not expression: raise AssertionError
Расширенная форма инструкции утверждения assert в Python.
assert expression1 expression2 # эквивалентно коду if __debug__: if not expression1: raise AssertionError(expression2)
Какие либо операции присвоения значения встроенной переменной __debug__ являются незаконными. Значение для встроенной переменной определяется при запуске интерпретатора.
Эти эквиваленты предполагают, что __debug__ и AssertionError ссылаются на встроенные переменные с этими именами. В текущей реализации встроенная переменная __debug__ имеет значение True при обычных обстоятельствах и False , когда запрашивается оптимизация — параметр командной строки -O .
Общий пример использования assert :
# Когда выражение в утверждении `assert` # истинно, то ничего не происходит >>> assert 2 5 # `assert` поднимает исключение `AssertionError` # если проверяемое выражение не выпоняется. >>> assert 2 > 5 Traceback (most recent call last): File "", line 1, in module> AssertionError
Обратите внимание, что нет необходимости включать в исходный код выражения, которое не удалось выполнить в сообщении об ошибке, оно будет отображаться как часть трассировки стека.
Вывод сообщения при ложном условии expression .
Оператор assert может включать необязательное сообщение message , которое позволяет лучше понять, почему код не сработал при ложном условии expression .
Пример утверждения assert с сообщением:
assert expression, message # пример >>> assert 2 + 2 == 5, "Houston we've got a problem" # Traceback (most recent call last): # File "", line 1, in # AssertionError: Houston we've got a problem
Не используйте круглые скобки для вызова assert как функции. assert — это заявление. Если выполнить assert(condition, message) , то будет запускаться assert с кортежем (condition, message) в качестве первого параметра!
Отключения утверждений assert .
Что касается отключения утверждений assert , то при запуске интерпретатора python в оптимизированном режиме, где __debug__ имеет значение False , утверждения assert будут игнорироваться. Для этого интерпретатору необходимо передать флаг -O :
$ python -O script.py
Лучшая практика использования утверждения assert .
Можно использовать дескрипторы классов, например чтобы иметь возможность автоматически выдавать ошибку, когда x становится меньше нуля во всей функции.
class LessThanZeroException(Exception): pass class variable(object): def __init__(self, value=0): self.__x = value def __set__(self, obj, value): if value 0: raise LessThanZeroException('x is less than zero') self.__x = value def __get__(self, obj, objType): return self.__x class MyClass(object): x = variable() >>> m = MyClass() >>> m.x = 10 >>> m.x -= 20 # Traceback (most recent call last): # File "", line 1, in # File "my.py", line 7, in __set__ # raise LessThanZeroException('x is less than zero') # LessThanZeroException: x is less than zero
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Обработка/перехват исключений try/except
- Инструкция finally, очистка внешних ресурсов
- Тонкости работы конструкции try/except/else/finally
- Создание пользовательского класса исключения
- Обработка группы исключений, оператор except*
- Эффективная обработка исключений
- Инструкция raise, принудительный вызов исключений
- Отладочные утверждение assert
- Улучшения сообщений об ошибках 3.10
- Улучшения сообщений об ошибках 3.11
- Улучшения сообщений об ошибках 3.12
assert
Инструкция assert позволяет производить проверки истинности утверждений, что может быть использовано в отладочных целях.
Если проверка не прошла, возбуждается исключение AssertionError.
Рекомендуется использовать инструкцию только для проверки внутреннего состояния программы — ситуаций, которые не должны происходить вовсе, которые нельзя обработать или это не имеет смысла (обычно это является указанием на то, что код программы содержит ошибку). Инструкция также может использоваться для документирования ожиданий (например, входных параметров или результата). В остальных случаях следует определять свои типы исключений.
passed = False
assert passed, 'Not passed' # Поднимается исключение.
# assert passed # Можно и не указывать текст описания, но рекомендуется.
# Запись выше эквивалентна следующей конструкции:
if __debug__:
if not passed:
raise AssertionError('Not passed')
# Пример правильного переноса строки описания:
assert a, ('Long exception '
'description chunked.')
# А теперь пример неправильного (передача кортежа),
# при котором проверка всегда проходит без ошибок:
assert (a, 'Long exception '
'description chunked.')
На заметку
В текущей реализации __debug__ — встроенная константа, по умолчанию имеющая значение True . Если интерпретатор запущен в режиме оптимизации (с флагом командной строки -O ), значение константы становится False , а генератор кода перестаёт производить байткод для рассматриваемой инструкции. Таким образом, отключив проверки, но не убирая их из кода, можно снизить неизбежные для них накладные расходы.
Оператор assert в Python: объяснение на примерах
Python – это универсальный язык программирования, позволяющий выполнять практически любые вычислительные задачи. Он обладает огромным количеством встроенных модулей, функций и ключевых слов, которые могут быть чрезвычайно полезны. Один из таких операторов – assert . Именно о нем мы поговорим сегодня.
Оператор assert – это встроенный оператор или ключевое слово в Python, используемое для отладки кода. Это своего рода проверка, которая исследует функциональность вашего кода.
Оператор assert работает как логическое выражение, проверяя, является ли заданное условие истинным или ложным. Если условие истинно, то ничего не происходит и выполняется следующая строка кода. Если же условие ложно, оператор assert останавливает выполнение программы и выдает ошибку. В этом случае assert работает как ключевое слово raise и выводит исключение. Исключение, вызванное оператором assert , также называется AssertionError .
В этой статье мы рассмотрим оператор assert в Python и разберем принципы его работы на нескольких примерах.
Синтаксис
Синтаксис использования оператора assert следующий:
assert
Также можно добавить дополнительное сообщение, которое будет выводиться при ошибке. В таком случае синтаксис assert будет следующий:
assert ,
Примеры
Чтобы разобраться, как пользоваться оператором assert на практике, давайте обсудим несколько примеров.
При выполнении операции деления следует учитывать, что на ноль делить нельзя. Если делитель будет равен нулю, программа вызовет ошибку ZeroDivisionError . Чтобы проверить, не равен ли делитель нулю, можно вставить оператор assert . Давайте реализуем это на Python.
num1 = 10 num2 = 0 assert num2 != 0, "The divisor is zero"
В assert мы указали условие, что num2 (делитель) не должен быть равен нулю. Данное условие не выполняется, потому что значение num2 равно нулю. Интерпретатор Python выдает ошибку AssertionError вместе с добавленным нами сообщением «The divisor is zero» («Делитель равен нулю»).
Теперь давайте изменим значение num2 и выполним нашу программу снова. На этот раз утверждение assert истинно, так что в этом случае ничего не произойдет. Ошибка не появляется, вместо этого выполняется следующая строка. Таким образом, на экран выведется результат деления — 1.0.
num1 = 10 num2 = 10 assert num2 != 0, "The divisor is zero" print("The result is:", num1/num2)
Теперь давайте разберем другой пример. Напишем условие assert для проверки корректности строки.
val = "Pythonist" assert val != "Pythonist", "The condition is false"
Условие не выполняется, поэтому выводится AssertionError .

Можно привести и альтернативный вариант примера со строкой:
val = "hello" assert val == "Pythonist", "The variable value is not equal to Pythonist"
Значение переменной val – hello. Это означает, что условие ложно, и программа выведет ошибку AssertionError с нашим комментарием — «The variable value is not equal to Pythonist».
Заключение
Оператор assert – это встроенный оператор в Python, позволяющий отлаживать код. Этот оператор принимает условие и необязательное сообщение, которое выводится, если условие assert ложно. В этом случае инструкция assert выводит AssertionError. Если условие истинно, то ничего не происходит и выполняется следующая строка кода. В этой статье мы подробно объяснили принцип работы оператора assert и разобрали его на примерах.
№35 Инструкция assert / для начинающих
Инструкции assert в Python — это булевы выражения, которые проверяют, является ли условие истинным ( True ). Они определяют факты (утверждения) в программе. Assertion — это проверка, которую можно включить, а затем выключить, завершив тестирование программы.
Возьмем простой пример функции деления. Можно быть уверенным в том, что делитель не должен быть нолем. Это и указывается при тестировании. Разберем этот пример позже.
Что такое Assertion (утверждение)
Assertions (утверждения) — это инструкции, которые «утверждают» определенный кейс в программе. В Python они выступают булевыми выражениями, которые проверяют, является ли условие истинным или ложным. Если оно истинно, то программа ничего не делает и переходит к выполнению следующей строчки кода.
Но если оно ложно, то программа останавливается и возвращает ошибку.
Следующий синтаксис — это базовая структура инструкций утверждения в Python.
assert condition
Если же нужно добавить сообщение для вывода при ложном условии, то синтаксис будет таким.
assert condition, message
Это сообщение позволит лучше понять, почему код не сработал.
Пример assert
Если нужно симулировать или выполнить отладку кода, чтобы узнать, что именно происходит на определенном этапе, то «утверждения» в Python отлично для этого подходят.
Именно инструмент отладки останавливает программу, как только возникает какая-то ошибка. Он также показывает, где именно она произошла.
- Инструкция assert принимает выражение и необязательное сообщение;
- Она используется для проверки типов, значений аргумента и вывода функции;
- А также для отладки, поскольку приостанавливает программу в случае ошибки.
Вот пример работы утверждений в Python.
def avg(ranks):
assert len(ranks) != 0
return round(sum(ranks)/len(ranks), 2)
ranks = [62, 65, 75]
print("Среднее значение:", avg(ranks))В этом примере нужно, чтобы пользователь не оставлял параметры пустыми. Если этого не сделать, вернется ошибка Assertion Error . Вот пример вывода:
Среднее значение: 67.33В этом случае параметры были переданы, поэтому функция вернула нужный результат.
Теперь попробуем ничего не передавать.
def avg(ranks):
assert len(ranks) != 0
return round(sum(ranks)/len(ranks), 2)
ranks = []
print("Среднее значение:", avg(ranks))Длина массива ranks оказалась 0, и python вернул ошибку Assertion Error .
Traceback (most recent call last): File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 6, in print("Среднее значение:", avg(ranks)) File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 2, in avg assert len(ranks) != 0 AssertionErrorИсключения Assertion Error можно перехватывать и обрабатывать как и любые другие исключения с помощью try-except. Но если их обработать неправильно, то программа остановится и вернет traceback .
Однако в примере выше она не возвращает ошибку с нужным сообщением. Ее можно написать самостоятельно. Вот как это делается.
def avg(ranks):
assert len(ranks) != 0, 'Список ranks не должен быть пустым'
return round(sum(ranks)/len(ranks), 2)
ranks = []
print("Среднее значение:", avg(ranks))Вторым аргументом к assert в примере выше было передано сообщение, которое позже появится в выводе.
Traceback (most recent call last): File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 6, in print("Среднее значение:", avg(ranks)) File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 2, in avg assert len(ranks) != 0, 'Список ranks не должен быть пустым' AssertionError: Список ranks не должен быть пустымAssert с сообщением об ошибки
Рассмотрим еще один пример с делением на 0.
def divide(x, y):
assert y != 0 , 'Нельзя делить на 0'
return round(x/y, 2)
z = divide(21,3)
print(z)
a = divide(21,0)
print(a)В этом примере, если делителем будет ноль, то assert вернет сообщение с ошибкой. Посмотрим на вывод.
7.0 Traceback (most recent call last): File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 8, in a = divide(21,0) File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 2, in divide assert y != 0 , 'Нельзя делить на 0' AssertionError: Нельзя делить на 0На третьей сверху строчке написана сама инструкция assert . Именно здесь проверяется, не является ли переменная y равной 0. Если она больше 0, то условие истинно, и код возвращает требуемый результат.
Но если вызвать метод division() со вторым аргументом 0, то условие assert будет ложным.
По этой причине и возникает исключение Assertion Error . Именно оно возвращает ошибку с сообщением «Нельзя делить на 0».
Методы assert
| Метод | Проверка на | Работает с |
|---|---|---|
| assertEqual(x, y) | x == y | |
| assertNotEqual(x, y) | x != y | |
| assertTrue(x) | bool(x) равно True | |
| assertFalse(x) | bool(x) равно False | |
| assertIs(x, y) | x это y | 3.1 |
| assertIsNot(x, y) | x это не y | 3.1 |
| assertIsNone(x) | x это None | 3.1 |
| assertIsNotNone(x) | x это не None | 3.1 |
| assertIn(x, y) | x в y | 3.1 |
| assertNotIn(x, y) | x не в y | 3.1 |
| assertIsInstance(x, y) | isinstance(x, y) | 3.2 |
| assertNotIsInstance(x,y) | не isinstance(x, y) | 3.2 |
Как проверить, что функция возвращает исключение
Можно использовать TestCase.assertRaises (или TestCase.failUnlessRaises ) из модуля unittest .
import unittest def broken_function():
raise Exception('Это ошибка') class MyTestCase(unittest.TestCase):
def test(self):
with self.assertRaises(Exception) as context:
broken_function()
self.assertTrue('Это ошибка' in str(context.exception)) if __name__ == '__main__':
unittest.main(). ---------------------------------------------------------------------- Ran 1 test in 0.051s OKРаспространенные ошибки
Есть два важных момента касательно утверждений в Python, о которых нужно помнить.
- Не стоит использовать assert для валидации данных, ведь это приводит к появлению проблем с безопасностью и багов.
- Важно не писать такие утверждения, которые всегда будут истинными.
Ключевые моменты assert в Python
- Утверждение (Assertion) — это условие или булево выражение, которое должно быть истинным.
- Инструкция assert принимает выражение и необязательное сообщение.
- Инструкция assert используется для проверки типов, значений аргументов и вывода функций.
- Это также инструмент для отладки, ведь он останавливает программу при появлении ошибки.
- В первую очередь утверждения используются для уведомления разработчиков о неотслеживаемых ошибках. Они не должны сообщать об условия ошибок, таких как «файл не был найден», где пользователь может попытаться исправиться и повторить действия.
- Утверждения — это внутренняя проверка для программы. Они работают за счет объявления невозможных условий в коде. Если эти условия не проходят, значит имеется баг.
