Вы можете иметь слишком много утверждений (в Python)? - PullRequest
6 голосов
/ 09 марта 2012

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

def register_symbol(self, symbol, func, keypress=None):
    assert(isinstance(symbol, basestring))
    assert(len(symbol) == 1)
    assert(callable(func))
    assert(keypress is None or type(keypress) is int)
    self.symbols_map[symbol] = (func, keypress)
    return

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

Ответы [ 3 ]

7 голосов
/ 09 марта 2012

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

assert(callable(func))

может быть примером для такого утверждения - если func не вызывается, вы получите сообщение об ошибке в совершенно другой строке кода, чем та, где находится фактическая ошибка, и это может быть не очевидно, как не вызываемый объект оказался в self.symbols_map. Я пишу «возможно», потому что это зависит от остальной части вашего кода - если это единственное место, где обновляется self.symbols_map, утверждение также может быть ненужным.

Первый и последний утверждения определенно противоречат идее типизации утки, , а второй является избыточным. Если symbol не является строкой длины 1, есть вероятность, что self.symbols_map[symbol] все равно поднимет KeyError, поэтому нет необходимости в утверждениях.

Последнее утверждение также неверно - type(keypress) не может быть None, и проверки типов должны выполняться с isinstance(). Могут быть очень специализированные приложения, в которых вы не можете разрешить подтипы, но проверка должна выполняться с type(x) is int вместо type(x) == int. Проверка на None должна выполняться x is None, а не type(x) is NoneType.

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

3 голосов
/ 09 марта 2012

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

2 голосов
/ 09 марта 2012

Имейте в виду, что операторы assert удаляются всякий раз, когда Python генерирует оптимизированный байт-код! Поскольку это имеет место в большинстве производственных сред, операторы assert не могут использоваться для проверки ввода. Фактически, я пришел к выводу, что я не могу использовать их вообще ни для чего, если не могу рассчитывать на их исполнение. Поэтому, если мне нужно проверить какое-то условие, я вместо этого использую «если ... поднять ...», и если я просто хочу проверить свой код, я пишу юнит-тесты.

...