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

Ram*_*hum 40 python assert exception

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

更新:

我将解释我的动机:到目前为止,我已经进行了断言式测试,这些测试提出了我自己的例外情况; 例如,当您Node使用某些参数创建对象时,它将检查参数是否适合创建节点,如果不是,则会引发NodeError.

但是我知道Python有一种-o跳过断言的模式,我希望它可用,因为它可以使我的程序更快.但我仍然希望有自己的例外.这就是为什么我想用自己的例外使用assert.

S.L*_*ott 53

这会奏效.但它有点疯狂.

try:
    assert False, "A Message"
except AssertionError, e:
    raise Exception( e.args )
Run Code Online (Sandbox Code Playgroud)

为什么不以下?这不那么疯狂了.

if not someAssertion: raise Exception( "Some Message" )
Run Code Online (Sandbox Code Playgroud)

它只比assert声明有点讽刺,但并没有违背我们对断言失败提出的期望AssertionError.

考虑一下.

def myAssert( condition, action ):
    if not condition: raise action
Run Code Online (Sandbox Code Playgroud)

然后你可以用这样的东西或多或少地替换现有的断言.

myAssert( {{ the original condition }}, MyException( {{ the original message }} ) )
Run Code Online (Sandbox Code Playgroud)

一旦你完成了这个,你现在可以随心所欲地启用或禁用或者你正在尝试做什么.

另外,请阅读警告模块.这可能正是你想要做的.

  • `try` 至少有一些开销操作码 - `SETUP_EXCEPT`、`JUMP_FORWARD`/`JUMP_ABSOLUTE` 和 `POP_BLOCK`。 (2认同)

Joh*_*ooy 24

这个怎么样?


>>> 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

Run Code Online (Sandbox Code Playgroud)

  • 这很美丽,但同时又如此被诅咒 (4认同)

Den*_*ach 8

if __debug__:使用-o选项运行时,Python也会跳过块.以下代码更详细,但您可以在没有黑客的情况下完成所需的操作:

def my_assert(condition, message=None):
    if not condition:
        raise MyAssertError(message)

if __debug__: my_assert(condition, message)
Run Code Online (Sandbox Code Playgroud)

您可以通过移动if __debug__:内部条件来缩短它my_assert(),但是在启用优化时它将被调用(内部没有任何操作).


iro*_*ggy 6

永远不要使用逻辑断言!仅用于可选的测试检查.请记住,如果Python在启用优化的情况下运行,则断言甚至不会编译为字节码.如果你这样做,你显然关心被引发的异常,如果你关心,那么你首先使用的是错误的断言.

  • 这样你至少可以让"优化"发挥作用.谁曾使用过优化!?一开始似乎毫无意义; 使用这样的更多断言至少为您提供了更多的优化选择,所以它很有趣. (2认同)

u0b*_*6ae 5

您可以让上下文管理器在 with 块(可能包含多个断言、更多代码和函数调用或您想要的内容)内为您进行转换。

from __future__ import with_statement
import contextlib

@contextlib.contextmanager
def myassert(exctype):
    try:
        yield
    except AssertionError, exc:
        raise exctype(*exc.args)

with myassert(ValueError):
    assert 0, "Zero is bad for you"
Run Code Online (Sandbox Code Playgroud)

请参阅此答案的先前版本以直接替换构造的异常对象 ( KeyError("bad key")),而不是重用断言的参数。