4

我有一种方法可以检查某些东西并且可以

  • 本身引发异常
  • 返回真
  • 返回假

我想正确地捕获异常以自己提出一个异常,但如果测试返回 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变量?

4

3 回答 3

10

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

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

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

编辑:如果异常相同,您也可以简单地执行此操作(Mark Byers 在他的回答中有这个,但现在已经消失了):

if not check():
    raise TheSameException()

如果 False,这将传播异常或引发。

于 2012-10-04T09:27:36.303 回答
2
try:
   # whatever
except MyException:
   raise # reraise it
except Exception as e:
   raise MyException(some_info(e)) # unify user-visible exception type
于 2012-10-04T09:23:43.103 回答
1

在 python 3.3 中,您可以使用新的contextlib.ExitStack上下文管理器

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()
于 2012-10-04T09:27:31.047 回答