С помощью инструкций assert в Python мы можем проверить условие на истинность, передав им факты (утверждения) приложения. Эту проверку можно как включить, так и выключить, закончив тестирование приложения. Для примера возьмем функцию деления. Здесь перед выполнением операции необходимо убедиться в том, что число не делится на ноль. При тестировании это указывается. Немного позже разберем этот пример.
Assertion – что это в Python?
Assertions в Python могут быть переведены, как «утверждения». Под этим словом подразумевается разновидность инструкций, которые «утверждают» определенный кейс в приложении. В Python они относятся к типу boolean и могут возвращать одно из значений: True или False.
Если проверка проходит успешно, интерпретатор больше ничего не делает, и просто переходит к следующему блоку кода. В случае ложности этого утверждения выполнение приложения останавливается с исключением. Инструкции утверждения в Python имеют следующий синтаксис.
assert condition
Если же нужно задать сообщение, которое будет показываться в случае возврата значения False, используется следующий синтаксис.
assert condition, message
Тогда будут более понятны причины неудачи при исполнении кода.
Инструкция assert на примере
Утверждения могут использоваться для проверки того, что происходит в определенный момент исполнения программы. То есть, это действенный инструмент отладки кода или его симуляции.
Как раз инструмент отладки и останавливает выполнение программы в случае возникновения ошибки и показывает, где возникло исключение.
Итак, что вам нужно знать о инструкции 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))
В результате, будет возвращена ошибка Assertion Error.
Traceback (most recent call last): File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 6, in <module> 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 – это полноценное исключение Python. Следовательно, его можно перехватывать, как и любое другое и обрабатывать с использованием ключевых слов try-except.
Но при неправильной обработке будет возвращен traceback, а программа завершит работу.
Тем не менее, в описанном выше примере нужное сообщение при ошибке не возвращается. Чтобы исправить эту проблему, его нужно написать самостоятельно. Делается это следующим образом.
def avg(ranks): assert len(ranks) != 0, 'Список ranks не должен быть пустым' return round(sum(ranks)/len(ranks), 2) ranks = [] print("Среднее значение:", avg(ranks))
Видим, что во втором аргументе инструкции была использована фраза «Список ranks не может быть пустым».
Соответственно, вывод будет следующим.
Traceback (most recent call last): File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 6, in <module> 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)
Здесь, как видим, во втором выражении число 21 делится на 0. Сначала программа попыталась разделить 21 на 3. Это у нее получилось, и было выдано значение 7.0.
А после этого возникло исключение «Нельзя делить на 0».
7.0 Traceback (most recent call last): File "C:/Users/asd/AppData/Local/Programs/Python/Python38/wb.py", line 8, in <module> 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 написана на второй сверху строке. Здесь выполняется проверка, является ли вторая переменная функции нулем. Если нет, то такое условие является истинным. Следовательно, код идет далее.
Но такая проверка справедлива лишь для функции divide(). Если же использовать метод division(), и там в качестве второго аргумента использовать ноль, то это условие будет ложным. Все потому, что это совсем другая функция.
Методы assert
Давайте теперь приведем таблицу с методами, которые могут быть использованы для инструкции 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, требуют обработки. Для этого используется конструкция try-except.
Вообще, исключения – это отдельный тип данных, предназначенный для сообщения разработчику об ошибке.
Давайте приведем пример использования этой конструкции.
>>> try: ... k = 1 / 0 ... except ZeroDivisionError: ... k = 0 ... >>> print(k) 0
Сначала у нас идет блок try. В нем мы выполняем инструкцию, которая может породить исключение. А в блоке except происходит ее перехват. Здесь осуществляется перехват как самого исключения, так и его потомков.
К слову, в этом примере мы использовали стандартный тип исключения ZeroDivisionError, не создавая отдельного утверждения для этого. Но логика обработки любых ошибок одинаковая.
Также можно использовать инструкцию except без аргументов. В таком случае она будет перехватывать абсолютно все ошибки. Правда, такая форма редко используется, поскольку перехватываются абсолютно все исключения, в том числе, и системный выход, прерывание с клавиатуры.
Следовательно, для перехвата исключения AssertionError необходимо написать соответствующий аргумент возле ключевого слова except. Также есть ключевое слово finally, которое выполняет блок инструкций, независимо от того, было исключение или нет.
А чтобы задать правило, что выполнение каких-то действий будет исключительно в случае, если исключения не было, используется инструкция else. Правда, нас она так не интересует, потому что при отсутствии исключения автоматически будет продолжаться выполнение кода. Тем не менее, этот метод обработки исключений также возможен.
Ключевые моменты assert в Python
Итак, давайте подведем итоги:
- Утверждение – это выражение, которое всегда должно быть истинным. Если оно оказывается ложным, выдается ошибка, текст которой можно записать самостоятельно.
- В качестве аргументов этой инструкции используются выражение и необязательное сообщение.
- Инструкция assert необходима для того, чтобы проверять типы данных, значения аргументов и результат выполнения функций.
- Этот инструмент очень популярен для отладки. Ведь если возникает ошибка, приложение попросту останавливается.
- В первую очередь утверждения используются для уведомления разработчиков об ошибках, которые нельзя отследить. Они не должны сообщать об условиях ошибок, где пользователь может внести коррективы.
- Утверждения не используются для взаимодействия с пользователем. Это лишь внутренняя проверка приложения. Необходимы они прежде всего для того, чтобы задать условия в коде, которые всегда будут невозможными. Деление на ноль – лучший пример. Если эти условия не проходят, значит, есть баг.
Таким образом, мы разобрались, как генерировать исключения в случае, если какое-то условие оказывается ложным.