Python утверждать с и без круглых скобок - PullRequest
84 голосов
/ 24 июня 2010

Вот четыре простых вызова 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 ]

103 голосов
/ 24 июня 2010

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

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

19 голосов
/ 07 июля 2015

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

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 и снова изменился с python 3.4 на 3.6. Создание утверждений assert не обратно совместимых ни с одной версией, ни с любой другой версией.

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

15 голосов
/ 24 июня 2010

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 - это ключевое слово.

8 голосов
/ 15 февраля 2018

Вы можете прервать утверждение assert без \, например:

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'
)
1 голос
/ 28 декабря 2017

Ниже цитируется документ python

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

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

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

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

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

...