带或不带括号的"assert"语句

149 投票
6 回答
65477 浏览
提问于 2025-04-16 00:23

这里有四个简单的使用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之间有什么区别,导致了这种情况呢?我通常习惯使用括号,但上面的例子似乎在暗示我不应该这样做。

6 个回答

36

你可以在不使用\的情况下,像这样来中断断言语句:

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'
)
56

如果你在这里加上括号是因为想写一个多行的断言,那么你可以选择在行末加一个反斜杠,像这样:

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

输出结果是:

AssertionError: "derp should be 8, it is 7

为什么这个 Python 的 assert 和其他的都不一样:

我觉得 Python 的设计理念是,程序应该能够自我修正,而不需要担心开启断言的特殊标志。关闭断言的诱惑太大了,所以这个功能正在被逐渐淘汰。

我理解你对 Python 的 assert 语法和其他 Python 语法不一样的烦恼,而且这种语法在 Python 2 到 Python 3 之间又发生了变化,从 Python 3.4 到 3.6 也又变了一次。这样一来,断言语句在不同版本之间就不兼容了。

这就像是在提醒你,assert 是个“第三类公民”,在 Python 4 中会被完全移除,肯定在 Python 8.1 中也会再次被移除。

163

最后那条 assert 语句如果在完整的解释器中运行,而不是在 IDLE 中,会给你一个警告(SyntaxWarning: assertion is always true, perhaps remove parentheses?)。这是因为 assert 是一个关键字,而不是一个函数,所以你实际上是把一个元组作为第一个参数传入,而第二个参数却没有给。

记住,非空的元组在判断时会被看作 True,而且因为断言信息是可选的,所以当你写 assert(1==2, "hi") 时,实际上你调用的是 assert True

撰写回答