python的设计:为什么断言声明而不是函数?

时间:2012-11-15 01:45:30

标签: python language-design assert

在Python中,assert是一个语句,而不是一个函数。这是一个刻意的决定吗?将assert作为声明(和保留字)而不是函数是否有任何好处?

根据the docsassert expression1, expression2已扩展为

if __debug__:
    if not expression1: raise AssertionError(expression2)

文档还说“当在编译时请求优化时,当前代码生成器不会为assert语句发出代码。”在不知道细节的情况下,似乎需要一个特殊情况才能实现这一目标。但是,一个特殊情况也可用于优化对assert()函数的调用。

如果assert是一个函数,你可以写:

assert(some_long_condition,
       "explanation")

但是因为assert是一个语句,所以元组总是求值为True,并且 你得到了

SyntaxWarning: assertion is always true, perhaps remove parentheses?

正确的写作方式是

assert some_long_condition, \
       "explanation"

可以说不太漂亮。

4 个答案:

答案 0 :(得分:31)

  

断言是声明(和保留字)而不是函数有什么好处吗?

  1. 无法重新分配给用户函数,这意味着它可以在编译时被有效禁用,如@mgilson指出的那样。
  2. 延迟第二个可选参数的评估,直到断言失败为止。使用函数和函数参数(需要传递lambda)这样做很尴尬。不推迟第二个参数的评估会引入额外的开销。

答案 1 :(得分:16)

python和其他语言(特别是C)中关于assert的一个很棒的事情是你可以通过添加正确的#define来删除它们以优化你的代码(可选地在命令行上我曾用过的任何编译器)或优化标志(python中的-O)。如果assert成为函数,则此功能将无法添加到python中,因为直到运行时才知道您是否具有内置assert函数或用户定义的同名函数。


另请注意,在python中,函数调用相当昂贵。用代码if __debug__: ...替换内联可能比执行函数调用更有效,如果在性能关键例程中放入assert语句,这可能很重要。

答案 2 :(得分:6)

我不是Python的专家,但我相信性能是其中一个最重要的原因。

如果我们将断言(表达式,解释)作为函数,如果表达式的计算成本很高,即使我们处于非调试模式,Python也需要计算两个表达式以将其传递给断言函数。

通过扩展断言,表达式和解释语句实际上不会被评估,除非确实需要它们(当 debug 计算结果为true时)。我认为,如果我们想要在不必要时使断言不影响性能(即在生产系统中没有性能损失),这是至关重要的。

答案 3 :(得分:6)

除了其他答案(以及一些偏离主题)的提示。为避免使用反斜杠,可以在括号内使用隐式线连接。 ; - )

而不是:

assert some_long_condition, \
       "explanation"

你可以写:

assert some_long_condition, (
       "explanation")