尽管有 -O(优化)标志,仍保持断言

max*_*max 2 python interpreter assert python-3.x

我对程序状态进行了多次检查,其失败将表明代码中存在错误。在这种情况下,我很乐意使用,assert condition因为它比if not condition: raise MyException.

使用assert代替raise有两个问题。

  1. assert不允许指定要引发的异常,因此稍后捕获它会变得困难(捕获AssertionError可能捕获太多)。

  2. assert当 -O 标志传递给解释器时禁用。

在我的环境中,代码中的任何错误都要求我放弃所有结果,直到识别并修复该错误。因此,捕获上述检查引发的异常是没有意义的。因此,问题#1 与我的情况无关。

问题#2 很严重。我希望我的检查保留在生产代码中,因为正确性比我的环境中的性能重要得多。如今很少有人使用 -O 标志;但有一天我或其他人可能更喜欢使用它(例如,抑制后面的代码if __debug__,或者因为 -O 可能在将来实际上优化代码)。由于我的所有assert语句都必须在生产代码中保持活动状态,因此我需要将所有assert语句替换为其他语句。assert尽管有 -O 标志,有什么方法可以强制留下来吗?

顺便说一句,我计划assert通过打印导致断言失败的行中的变量值来自定义行为。我想我可以通过替换sys.excepthook为我自己的函数来实现它,该函数捕获AssertionError,读取回溯,找到相关的源代码,打印相关行中的变量,然后重新引发异常。如果有人发现有问题,请告诉我。

小智 7

如果断言不是您所需要的,请不要使用它们。相反,要明确表示如果违反某些条件,您将抛出此异常。断言语句总是带有“我可能会也可能根本不会运行”的一面。它不那么老套,不那么令人惊讶,将来不太可能出现问题,并且不需要您阻止用户添加-O.

如果您只是想节省打字时间,也可以这样做。创建一个像这样的函数(强烈建议使用更具体的名称)并使用它而不是assert

def require(cond, msg):
    if not cond:
        raise MyException(msg)
Run Code Online (Sandbox Code Playgroud)