让Python的`assert`抛出我选择的异常

59 投票
8 回答
59063 浏览
提问于 2025-04-15 15:04

我可以让 assert 抛出我自己选择的异常,而不是 AssertionError 吗?

更新:

我来解释一下我的想法:到目前为止,我一直在使用断言风格的测试,这些测试会抛出我自己定义的异常。例如,当你用某些参数创建一个 Node 对象时,它会检查这些参数是否适合创建一个节点,如果不适合,就会抛出 NodeError

但是我知道 Python 有一个 -o 模式,在这个模式下,断言会被跳过,我希望能使用这个模式,因为这样可以让我的程序运行得更快。不过,我还是想保留我自己的异常。这就是我想用断言来抛出我自己异常的原因。

8 个回答

16

千万不要把断言用来做逻辑判断!它只适合用来做一些可选的测试检查。记住,如果Python在优化模式下运行,断言根本不会被编译成字节码。如果你在这样做,说明你很在意异常的出现,但如果你在意这些,那你一开始就用错了断言。

28

这样怎么样?


>>> def myraise(e): raise e
... 
>>> cond=False
>>> assert cond or myraise(RuntimeError)
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in myraise
RuntimeError

68

这个方法可以用,但有点疯狂。

try:
    assert False, "A Message"
except AssertionError, e:
    raise Exception( e.args )

那为什么不试试下面这个呢?这样会更简单一些。

if not someAssertion: raise Exception( "Some Message" )

这个写法比 assert 语句稍微多了一点字,但不会打破我们对 assert 失败时会抛出 AssertionError 的预期。

想想这个。

def myAssert( condition, action ):
    if not condition: raise action

然后你可以差不多把现有的断言替换成这样的东西。

myAssert( {{ the original condition }}, MyException( {{ the original message }} ) )

一旦你这样做了,你就可以随意调整启用或禁用,或者你想做的其他事情。

另外,看看 warnings 模块的内容。这可能正是你想要做的事情。

撰写回答