在处理异常时,上下文管理器能否导致它所在的函数为return
?
我有一些尝试 - 除了我正在写的几种方法常见的模式,我希望用上下文管理器来干掉它。如果存在Exception
,则该函数需要停止处理。
以下是我当前实施的一个示例:
>>> class SomeError(Exception):
... pass
...
>>> def process(*args, **kwargs):
... raise SomeError
...
>>> def report_failure(error):
... print('Failed!')
...
>>> def report_success(result):
... print('Success!')
...
>>> def task_handler_with_try_except():
... try:
... result = process()
... except SomeError as error:
... report_failure(error)
... return
... # Continue processing.
... report_success(result)
...
>>> task_handler_with_try_except()
Failed!
有没有办法干掉try-except,以便在SomeError
被引发时返回任务处理函数?
注意:任务处理程序由库中的代码调用,该代码不处理从任务处理函数生成的异常。
这是一次尝试,但会导致UnboundLocalError
:
>>> import contextlib
>>> @contextlib.contextmanager
... def handle_error(ExceptionClass):
... try:
... yield
... except ExceptionClass as error:
... report_failure(error)
... return
...
>>> def task_handler_with_context_manager():
... with handle_error(SomeError):
... result = process()
... # Continue processing.
... report_success(result)
...
>>> task_handler_with_context_manager()
Failed!
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 6, in task_handler_with_context_manager
UnboundLocalError: local variable 'result' referenced before assignment
是否可以使用上下文管理器来干掉这种模式,还是有替代方案?
答案 0 :(得分:1)
不,上下文管理员无法做到这一点,因为您只能return
来自其正文中的函数。
但是,您正在寻找的东西确实存在!它被称为装饰者。
def handle_errors(func):
def inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except SomeError as error:
report_failure(error)
return
return inner
@handle_errors
def task_handler():
result = process()
report_success(result)
请注意,如果您一直想要report_success
,那么您可以进一步干掉它!
def report_all(func):
def inner(*args, **kwargs):
try:
ret = func(*args, **kwargs)
report_success(ret)
return ret
except SomeError as error:
report_failure(error)
return
return inner
@report_all
def task_handler():
return = process()
你根本不需要任务处理程序:
@report_all
def process():
# ...