在Python中,
assert
是一个语句,而不是一个函数。
根据文档,
assert expression1, expression2
相当于
if __debug__:
if not expression1:
raise AssertionError(expression2)
文档还说
在编译时请求优化时,当前代码生成器不会为断言语句发出任何代码。
在不了解细节的情况下,似乎需要特殊情况才能实现这一点。但是,也可以使用特殊情况来优化对
assert()
函数的调用。
如果
assert
是一个函数,你可以写:
assert(some_long_condition,
"explanation")
但是因为
assert
是一个语句,所以元组的计算结果总是为 True
,你会得到
SyntaxWarning: assertion is always true, perhaps remove parentheses?
多行书写的正确方法是
assert some_long_condition, \
"explanation"
为什么做出这个决定?使用
assert
作为语句(和 保留字)而不是函数有优势吗?
使用断言作为语句(和保留字)而不是函数有什么优点吗?
Python 和其他语言(特别是 C)中的
assert
的美妙之处之一是,您可以通过添加正确的 #define
来删除它们来优化代码(可选地在命令行上使用我曾经使用过的任何编译器)使用)或优化标志(Python 中的-O
)。 如果 assert
成为一个函数,这个功能将无法添加到 python 中,因为直到运行时你才知道你是否有内置 assert
函数或同名的用户定义函数。
还要注意,在 python 中,函数调用的开销相当大。 用代码
if __debug__: ...
替换内联可能比执行函数调用更有效,如果您将 assert
语句放入性能关键例程中,这可能会很重要。
除了其他答案(以及有点题外话)之外,还有一个提示。为了避免使用反斜杠,您可以在括号内使用隐式行连接。 ;-)
代替:
assert some_long_condition, \
"explanation"
你可以写:
assert some_long_condition, (
"explanation")
我不是Python专家,但我相信性能是最大的原因之一。
如果我们有断言(表达式,解释)作为函数,如果表达式的计算成本很高,即使我们处于非调试模式,Python也需要计算两个表达式以将其传递给断言函数。
通过扩展断言,表达式和解释语句实际上不会被求值,除非它们确实需要(当 debug 求值为 true 时)。 我认为,如果我们想让断言在不必要时不影响性能(即在生产系统中不影响性能),这一点至关重要。