python assert с круглыми скобками и без них


вот четыре простых вызова assert:

>>> assert 1==2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert 1==2, "hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError: hi

>>> assert(1==2)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert(1==2, "hi")

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

5 74

5 ответов:

последние assert дал бы вам предупреждение (SyntaxWarning: assertion is always true, perhaps remove parentheses?) Если вы запустили его через полный интерпретатор, а не через IDLE. Потому что assert является ключевым словом, а не функцией, вы фактически передаете Кортеж в качестве первого аргумента и оставляете второй аргумент.

Напомним, что непустые кортежи оцениваются в True, и поскольку сообщение утверждения является необязательным, вы по существу вызвали assert True когда ты писал assert(1==2, "hi").

assert 1==2, "hi" анализируется как assert 1==2, "hi" с "привет" в качестве второго параметра для сайта. Поэтому он правильно выдает ошибку.

assert(1==2) анализируется как assert (1==2), что соответствует assert 1==2, потому что парены вокруг одного элемента не создают кортеж, если нет конечной запятой, например (1==2,).

assert(1==2, "hi") анализируется как assert (1==2, "hi"), который не дает ошибку, потому что непустой кортеж (False, "hi") не является ложным значением, и второй параметр не предоставляется ключевое слово.

вы не должны использовать скобки, потому что assert - это не функция в Python - это ключевое слово.

если вы ставите скобки там, потому что вы хотели многострочное утверждение, то альтернативой является поставить обратную косую черту в конце строки следующим образом:

foo = 7
assert foo == 8, \
    "derp should be 8, it is " + str(foo)

принты:

AssertionError: "derp should be 8, it is 7

почему этот питон assert должны отличаться от всего остального:

Я думаю, что подходящие для Python идеологии заключается в том, что программа должна самостоятельно исправить, не беспокоясь о специальный флаг, чтобы включить утверждает. Соблазн выключить утверждает тоже есть великий, и, таким образом, это осуждается.

Я разделяю ваше раздражение, что питон assert имеет уникальный синтаксис по отношению ко всем другим конструкциям программирования python, и этот синтаксис снова изменился с python2 на python3, делая утверждения не обратно совместимыми.

это удар по плечу, что assert является гражданином 3-го класса, он будет полностью удален в python4 и, конечно же, снова в Python 8.1.

вы можете разбить утверждение утверждение без \ такой:

foo = 7
assert foo == 8, (
    'derp should be 8, it is ' + str(foo))

или если у вас есть еще более длинное сообщение:

foo = 7
assert foo == 8, (
    'Lorem Ipsum is simply dummy text of the printing and typesetting '
    'industry. Lorem Ipsum has been the industry\'s standard dummy text '
    'ever since the 1500s'
)

следующее цитируется из python doc

операторы Assert-это удобный способ вставки утверждений отладки в программу:

assert_stmt ::= "assert" expression ["," expression]

простая форма, утверждают, выражение, эквивалентно if __debug__: if not expression: raise AssertionError

расширенная форма, assert expression1, expression2, эквивалентно if __debug__: if not expression1: raise AssertionError(expression2)

поэтому, когда вы используете скобки здесь, вы используете простую форму, и выражение вычисляется как кортеж, что всегда верно при приведении к bool