pythonic在try块中引发错误的方法

时间:2012-10-04 09:19:43

标签: python exception-handling try-catch

我有一个方法可以检查某些内容,哪些可以

  • 自己提出异常
  • return True
  • 返回False

我想正确地捕获异常以自己引发异常,但是如果测试返回False也是如此。不正确的方法是

try:
    if not check():
        raise MyException()
except:
    raise MyException()

MyException之后再次抓住第一个except。正确处理这个问题的一种方法是

try:
    flag = check()
except:
    raise MyException()
else:
    if not flag:
        raise MyException()

这是处理这种情况的唯一方法,还是有另一种方法可以更有效地处理它,摆脱flag变量?

3 个答案:

答案 0 :(得分:7)

你永远不应该使用except:因为它捕获所有异常,包括SystemExit,你应该这样做:

try:
    if not check():
        raise MyNewException()
except ExceptionRaisedByCheck:
    raise MyNewException()

如果来自check()的异常与您要引发的异常相同,则应更改该异常。

编辑:如果异常相同,你也可以这样做(Mark Byers在他的回答中有这个,但现在已经消失了):

if not check():
    raise TheSameException()

这会传播异常,如果为False则会提升。

答案 1 :(得分:2)

try:
   # whatever
except MyException:
   raise # reraise it
except Exception as e:
   raise MyException(some_info(e)) # unify user-visible exception type

答案 2 :(得分:1)

在python 3.3中,您可以使用新的contextlib.ExitStack context manager

with ExitStack() as stack:
    stack.callback(lambda: raise MyException)

    if check():
        stack.pop_all()

这将引发MyException,除非您使用pop_all()清除堆栈回调。

您可以将其编入自定义上下文管理器:

from contextlib import ExitStack

class ExceptionUnlessCancelled(ExitStack):
    def __init__(self, exception, *args, **kw):
        super(Callback, self).__init__()
        self.exception = exception
        self.callback(self.raiseException, *args, **kwds)

    def raiseException(self, *args, **kw):
        raise self.exception(*args, **kw)

    def cancel(self):
        self.pop_all()

with ExceptionUnlessCancelled(MyException) as exc:
    if check():
        exc.cancel()