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

时间:2012-03-29 16:25:28

标签: python python-3.x interpreter assert

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

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

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

  2. 将-O标志传递给解释器时,
  3. assert被禁用。

  4. 在我的环境中,代码中的任何错误都要求我在发现并修复错误之前丢弃任何结果。因此,抓住上述检查引起的例外是没有意义的。因此,问题#1与我的情况无关。

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

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

1 个答案:

答案 0 :(得分:3)

如果它们不是您需要的,请不要使用断言。而是明确表示如果违反某些条件,您将抛出此异常。断言语句总是带有“我可能会或可能根本不会运行”。它不那么骇人,不那么惊人,以后不太可能破坏,并且不要求你阻止用户添加-O

如果您只想保存输入,可以这样做。创建这样的函数(强烈建议使用更具体的名称)并使用它而不是assert

def require(cond, msg):
    if not cond:
        raise MyException(msg)