126

这里有四个简单的 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")

请注意,最后一个不会引发错误。带或不带括号调用断言导致此行为有什么区别?我的做法是使用括号,但以上建议我不应该。

4

5 回答 5

150

如果您通过完整的解释器而不是通过 IDLE 运行,最后一个assert会给您一个警告 ( )。SyntaxWarning: assertion is always true, perhaps remove parentheses?因为assertis 是关键字而不是函数,所以您实际上是在传递一个元组作为第一个参数并省略第二个参数。

回想一下,非空元组的计算结果为True,并且由于断言消息是可选的,因此您在assert True编写 时实际上已经调用了assert(1==2, "hi").

于 2010-06-24T17:00:58.230 回答
42

如果你把括号放在那里是因为你想要一个多行断言,那么另一种方法是在行尾放一个反斜杠,如下所示:

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

印刷:

AssertionError: "derp should be 8, it is 7

为什么这条蟒蛇assert必须与其他一切不同:

我认为 Pythonic 的意识形态是程序应该自我纠正,而不必担心打开断言的特殊标志。关闭断言的诱惑太大了,因此它被弃用了。

我和你一样烦恼的是,pythonassert相对于所有其他 python 编程结构具有独特的语法,并且这种语法再次从 python2 更改为 python3,并再次从 python 3.4 更改为 3.6。使断言语句不能从任何版本向后兼容到任何其他版本。

assert是一个三等公民的肩膀上的轻拍,它将在 python4 中完全删除,当然在 Python 8.1 中也会再次删除。

于 2015-07-07T15:16:02.490 回答
21

你可以打破断言语句,而\不像这样:

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'
)
于 2018-02-15T07:27:27.757 回答
18

assert 1==2, "hi"被解析为assert 1==2, "hi"将“hi”作为关键字的第二个参数。因此,为什么它正确地给出了错误。

assert(1==2)被解析为assert (1==2)which 与 相同assert 1==2,因为围绕单个项目的括号不会创建元组,除非有尾随逗号,例如(1==2,).

assert(1==2, "hi")被解析为assert (1==2, "hi"),它不会给出错误,因为非空元组(False, "hi")不是假值,并且没有提供给关键字的第二个参数。

你不应该使用括号,因为assert它不是 Python 中的函数——它是一个关键字。

于 2010-06-24T17:03:17.663 回答
1

以下是从python doc中引用的

断言语句是将调试断言插入程序的便捷方式:

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

简单的形式,断言表达式,等价于 if __debug__: if not expression: raise AssertionError

扩展形式 assert expression1, expression2等价于 if __debug__: if not expression1: raise AssertionError(expression2)

所以当你在这里使用括号时,你使用的是简单的形式,并且表达式被评估为一个元组,当被强制转换为 bool 时它总是 True

于 2017-12-28T06:44:44.360 回答