我还发现很多次我需要对所引发的错误进行“包装”。
这包括在函数范围内,有时只包含函数内的一些行。
创建了一个包装器,用于do2和context manager:
履行
import inspect
from contextlib import contextmanager, ContextDecorator
import functools
class wrap_exceptions(ContextDecorator):
def __init__(self, wrapper_exc, *wrapped_exc):
self.wrapper_exc = wrapper_exc
self.wrapped_exc = wrapped_exc
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
if not exc_type:
return
try:
raise exc_val
except self.wrapped_exc:
raise self.wrapper_exc from exc_val
def __gen_wrapper(self, f, *args, **kwargs):
with self:
for res in f(*args, **kwargs):
yield res
def __call__(self, f):
@functools.wraps(f)
def wrapper(*args, **kw):
with self:
if inspect.isgeneratorfunction(f):
return self.__gen_wrapper(f, *args, **kw)
else:
return f(*args, **kw)
return wrapper
用法示例
装饰
@wrap_exceptions(MyError, IndexError)
def do():
pass
当调用do2方法时,不要担心context manager,只需IndexError
try:
do()
except MyError as my_err:
pass # handle error
上下文经理
def do2():
print('do2')
with wrap_exceptions(MyError, IndexError):
do()
内部do2,在context manager,如果IndexError被提出,它将被包裹和提出MyError