Сообщить об ошибке.

Отладочные утверждения 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 "<stdin>", 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 "<stdin>", line 1, in <module>
# 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 "<stdin>", line 1, in <module>
#   File "my.py", line 7, in __set__
#     raise LessThanZeroException('x is less than zero')
# LessThanZeroException: x is less than zero