我有一个方法可以检查某些内容,哪些可以
我想正确地捕获异常以自己引发异常,但是如果测试返回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
变量?
答案 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()