在Python __exit__块内重新抛出异常
在一个自定义光标类的__exit__
块中,我想捕获一个异常,这样我就可以抛出一个更具体的异常。这样做的正确方法是什么呢?
class Cursor:
def __enter__(self):
...
def __exit__(self, ex_type, ex_val, tb):
if ex_type == VagueThirdPartyError:
# get new more specific error based on error code in ex_val and
# return that one in its place.
return False # ?
else:
return False
在__exit__
块中抛出具体的异常感觉有点像是个小技巧,但也许我想得太复杂了。
1 个回答
30
正确的做法是在 __exit__
处理器里面抛出新的异常。
不过,你不应该抛出传入的那个异常;这样做是为了支持上下文管理器的链式调用。在这种情况下,你只需要从处理器返回一个“假值”(也就是表示“没有”或“失败”的值)。但是,抛出你自己定义的异常是完全可以的。
需要注意的是,最好使用身份测试 is
来验证传入异常的类型:
def __exit__(self, ex_type, ex_val, tb):
if ex_type is VagueThirdPartyError:
if ex_val.args[0] == 'foobar':
raise SpecificException('Foobarred!')
# Not raising a new exception, but surpressing the current one:
if ex_val.args[0] == 'eggs-and-ham':
# ignore this exception
return True
if ex_val.args[0] == 'baz':
# re-raise this exception
return False
# No else required, the function exits and `None` is returned
你也可以使用 issubclass(ex_type, VagueThirdPartyError)
来允许特定异常的子类。