我对程序状态进行了很多检查,其失败表明代码中存在错误。在这种情况下,我很乐意使用assert condition
,因为它比if not condition: raise MyException
更好。
使用assert
代替raise
有两个问题。
assert
不允许指定要引发的异常,因此稍后捕获它会变得很难(捕获AssertionError
可能会捕获太多)。
assert
被禁用。
在我的环境中,代码中的任何错误都要求我在发现并修复错误之前丢弃任何结果。因此,抓住上述检查引起的例外是没有意义的。因此,问题#1与我的情况无关。
问题#2很严重。我希望我的支票保留在生产代码中,因为正确性远比环境中的性能重要。今天很少有人使用-O标志;但是有一天我或其他人可能更喜欢使用它(例如,抑制if __debug__
后面的代码,或者因为-O可能会在将来实际优化代码)。由于我的所有assert
语句必须在生产代码中保持活动状态,因此我需要将所有assert
语句替换为其他语句。尽管有-O标志,有没有办法迫使assert
留下来?
顺便说一句,我打算通过从导致断言失败的行打印变量值来自定义assert
的行为。我想我可以通过用我自己的函数替换sys.excepthook
来捕获AssertionError
,读取回溯,找到相关的源代码,从相关行打印变量,然后重新引发异常。如果有人发现问题,请告诉我。
答案 0 :(得分:3)
如果它们不是您需要的,请不要使用断言。而是明确表示如果违反某些条件,您将抛出此异常。断言语句总是带有“我可能会或可能根本不会运行”。它不那么骇人,不那么惊人,以后不太可能破坏,并且不要求你阻止用户添加-O
。
如果您只想保存输入,可以这样做。创建这样的函数(强烈建议使用更具体的名称)并使用它而不是assert
:
def require(cond, msg):
if not cond:
raise MyException(msg)