以下是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")
请注意,最后一个不会引发错误。调用带或不带括号的断言会导致这种行为有什么区别?我的做法是使用括号,但上面的建议我不应该这样做。
答案 0 :(得分:102)
如果您通过完整的解释程序运行,而不是通过IDLE,则最后assert
会给您一个警告(SyntaxWarning: assertion is always true, perhaps remove parentheses?
)。因为assert
是关键字而不是函数,所以实际上是将元组作为第一个参数传递而不是第二个参数。
回想一下,非空元组的计算结果为True
,并且因为断言消息是可选的,所以当你编写assert True
时,你基本上调用了assert(1==2, "hi")
。
答案 1 :(得分:19)
如果你把括号放在那里因为你想要一个多行断言,那么另一种方法就是在行的末尾放一个反斜杠:
foo = 7
assert foo == 8, \
"derp should be 8, it is " + str(foo)
打印:
AssertionError: "derp should be 8, it is 7
assert
必须与其他所有内容不同:我认为pythonic意识形态是程序应该自我纠正而不必担心打开断言的特殊标志。关闭断言的诱惑太大了,因此它被弃用了。
我分享你的烦恼,python assert
具有相对于所有其他python编程结构的独特语法,并且这种语法再次从python2更改为python3并再次从python 3.4更改为3.6。
使断言语句不能从任何版本向后兼容任何其他版本。
这是assert
是三等公民的肩膀,它将在python4中被完全删除,当然也会在Python 8.1中被删除。
答案 2 :(得分:15)
assert 1==2, "hi"
被解析为assert 1==2, "hi"
,其中“hi”为关键字的第二个参数。因此,为什么它恰当地给出了错误。
assert(1==2)
被解析为assert (1==2)
,与assert 1==2
相同,因为围绕单个项目的parens不会创建元组,除非有一个尾随逗号,例如(1==2,)
。
assert(1==2, "hi")
被解析为assert (1==2, "hi")
,它不会出错,因为非空元组(False, "hi")
不是false值,并且没有提供第二个参数关键字。
你不应该使用括号,因为assert
不是Python中的函数 - 它是一个关键字。
答案 3 :(得分:7)
你可以在不使用\
的情况下破坏断言语句:
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'
)
答案 4 :(得分:1)
以下引自python doc
断言语句是将调试断言插入程序的便捷方式:
assert_stmt ::= "assert" expression ["," expression]
简单形式断言表达式等同于
if __debug__:
if not expression: raise AssertionError
扩展形式,断言表达式1,表达式2 ,相当于
if __debug__:
if not expression1: raise AssertionError(expression2)
所以当你在这里使用括号时,你正在使用简单的形式,而表达式被评估为一个元组,当被转换为bool时它总是为真