python的devise:为什么要声明一个声明而不是一个函数?

在Python中, assert是一个声明,而不是一个函数。 这是一个蓄意的决定吗? assert声明(和保留字)而不是函数有什么好处吗?

根据文档 , assert 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" 

这可以说是不太漂亮。

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

  1. 不能被重新分配给用户函数,这意味着它可以在编译时被有效地禁用@mgilson指出。
  2. 第二个可选参数的评估被推迟到断言失败时。 不好意思的是用函数和函数参数(需要传递lambdaexpression式)。不推迟第二个参数的评估会带来额外的开销。

在python和其他语言(特别是C)中assert一个奇妙的事情是,你可以删除它们来优化你的代码,只需添加正确的#define (可选地在命令行中使用我曾经使用的任何编译器)或优化标志( -O在Python中)。 如果assert成为一个函数,这个function是不可能添加到Python,因为你不知道,直到运行时,你是否有内置assertfunction或用户定义的函数具有相同的名称。


另外请注意,在Python中,函数调用相当昂贵。 if __debug__: ...比使用函数调用更有效率,如果将assert语句放在性能关键的例程中,这可能是非常重要的。

我不是Python的专家,但我相信性能是最大的原因之一。

如果我们已经声明(expression式,解释)作为函数,如果expression式评估昂贵,即使我们处于非debugging模式,Python也需要评估这两个expression式以将其传递给断言函数。

通过扩展断言,除非确实需要(当debugging结果为真时),否则expression式和解释语句实际上不会被评估。 我认为,如果我们不想在不需要的情况下(即在生产系统中没有性能影响)声明不影响性能,这是至关重要的。

除了其他的答案(和sorting题外话)小费。 为了避免使用反斜杠,可以使用括号内的隐式行连接。 😉

代替:

 assert some_long_condition, \ "explanation" 

你可以写:

 assert some_long_condition, ( "explanation")