最佳实践似乎是assert
用于在代码正确的情况下永远不会发生的条件,以及用于有点不寻常但可能发生的条件的异常(例如,当内存用完或用户输入无效时,或者外部连接断开)。我理解这种做法背后的基本原理如下:
assert
将使用 -O 解释器标志禁用。不能允许由外部因素引起的条件被默默地忽略,所以断言有不合适的。OTOH,只有在我的代码不正确时才可能出现的情况有望通过测试和调试消除,所以assert
很好。assert
阻止调用者处理异常,因为AssertionError
通常被解释为“不要抓住我,这是一个灾难性的失败”。此外,它太笼统而无法捕捉。当发现错误时,这是完美的;对此的典型处理是停止执行并调试代码。如果是外部原因导致的常见情况,那就不好了。
假设我编写了一些代码来确保某个函数参数始终为正。如果我发现它是否定的,显然我在代码中犯了一个错误。因此,我assert
认为这个论点是积极的。
后来,有人发现这个功能在另一个应用程序中很有用。他们导入它,并向它发送各种数据。现在从我的功能的角度来看,实际上很有可能收到负值;它只是一个无效的用户输入。可以说,assert
不再合适,应该用例外替换。
由于几乎任何代码都有可能在某一天被重用,而且通常在我不知情的情况下,这个论点似乎在说“从不使用assert
;只使用异常”。显然,这不是公认的做法。我错过了什么?
编辑:
更具体地说,假设该函数根本无法处理否定参数。因此,一旦参数为负,该函数将执行以下操作之一:
- 引发异常
- 断言失败
- 继续执行,可能产生不正确的输出
我可以看到,如果调用者捕捉到否定论点,那该有多好。但是,如果对函数的调用散布在代码周围的几十个地方,那么由于多次重复相同的检查,这可能会损害代码的清晰度。(更不用说,它可能会不小心忘记。)