我对 Python assert 语句的使用有不同的看法,我希望你能告诉我为什么我错了

I have a different opinion about my usage of the Python assert statement and I would like you to tell me why I am wrong

请听我说完。我知道 assert 是如何工作的。

对于上下文,我想到的一些应用程序和用法涉及通过 GUI 进行数学优化,因此这些函数可以被调用数亿次。

assert 语句在优化模式 (-O) 中被禁用,因此依赖它被认为是不好的做法(阅读:capital sin)根据大多数人的意见(也许这不仅仅是一种意见,我不知道)。

假设我有以下计算圆面积的函数:

def area_circle(r):
    return 3.141592654 * (r**2)

是的,我知道,没有文档字符串。这是一个玩具示例。为了确保 radiusintfloat,我会这样做:

def area_circle(r):
    assert isinstance(r, (int, float), 'TypeError: Expected int or float, not ' + type(r).__name__
    return 3.141592654 * (r**2)

我对它的看法可能应该让我公开处决,因为我认为它是一个很好的功能,允许我在开发时进行一些输入检查等,但是当我达到生产就绪状态时,我可以在优化模式下禁用那些不必要的代码部分。如果我的系统测试涵盖导致使用 area_circle 的工作流,那么我个人不想看到 raise 语句,因为它们只是浪费。

那么,如何在不使用 assert 的情况下以不减慢应用程序的方式进行集成系统测试?

编辑 1

这里有两条额外的信息需要考虑:

  1. 没有外部数据来源,一切都来自 图形用户界面;
  2. 输入验证直接在 GUI 中完成

您的论点似乎是 assert 语句非常适合调试(确实如此),并且 您的用例中 可以对每个代码路径进行充分的单元测试,您可以在生产过程中自信地关闭它们以获得性能,并且您现在怀疑 every 可能使用显式 raise 语句。

嗯,并不是每个代码都可以测试到那个程度。有代码 "at the frontlines" 必须在运行时 进行输入验证 ,并且必须使用显式检查和显式 raise 语句。很高兴 you 有这样一种情况,您的后端代码不需要担心输入验证,因为您有足够的信心认为这是在前一层处理的。在这种情况下,一定不要进行输入验证并关闭 assert 语句。这并不意味着在任何情况下都是可能的。例如,您的前端仍然需要明确的运行时检查,并且可能会在内部明确 raise 错误。

raise 语句适用于当您的程序遇到无法处理的 异常情况 时。您的代码向远程服务器发出 HTTP 请求,该服务器以 [​​=16=] 响应。这是特殊情况。这不是您的代码的快乐路径。这是你的代码无法处理的情况,它只能在运行时发生,没有办法通过单元测试来防止这种情况。在这种情况下,raise抛出异常是一件非常明智的事情。