我对程序状态进行了许多检查,如果检查失败将表明代码中存在错误。在这种情况下,我很想使用assert condition
仅仅是因为它比if not condition: raise MyException
读起来更好。
使用assert
代替raise
有两个问题。assert
不允许指定要引发的异常,因此以后捕获它会变得很困难(捕获AssertionError
可能会捕获太多)。
当-O标志传递给解释器时,assert
被禁用。
在我的环境中,代码中的任何错误均要求我放弃所有结果,直到识别并修复该错误为止。因此,毫无意义地捕获上述检查引发的异常。因此,问题1与我的情况无关。
问题2很严重。我希望我的检查保留在生产代码中,因为在我的环境中正确性比性能要重要得多。今天很少有人使用-O标志;但是有一天,我或其他人可能更喜欢使用它(例如,禁止显示if __debug__
后面的代码,或者因为-O将来可能会实际优化代码)。由于我的所有assert
语句必须在生产代码中保持活动状态,因此我需要将所有assert
语句替换为其他内容。尽管有-O标志,有什么办法可以迫使assert
停留?
顺便说一句,我打算通过打印导致断言失败的行中的变量值来自定义assert
的行为。我想我可以通过用自己的捕获sys.excepthook
的函数替换AssertionError
,读取回溯,找到相关的源代码,从相关行中打印变量,然后重新引发异常来实现。如果有人发现问题,请告诉我。
最佳答案
只是不要使用断言,如果它们不是您所需要的。相反,要明确指出,如果违反某些条件,则会引发此异常。 assert语句始终带有“我可能会运行,也可能不会运行”这一面。它不那么骇人听闻,不那么令人惊讶,将来也不太可能被破坏,也不需要您阻止用户添加-O
。
如果您只想保存键入内容,可以这样做。创建这样的函数(强烈建议使用更具体的名称)并使用它代替assert
:
def require(cond, msg):
if not cond:
raise MyException(msg)