编写一个或多个异常处理函数,给定一个函数和其中引发的异常,执行您想要执行的操作(例如显示警报)。如果你需要不止一个,写出来。
def message(func, e):
print "Exception", type(e).__name__, "in", func.__name__
print str(e)
现在编写一个装饰器,将给定的处理程序应用于被调用的函数:
import functools
def handle_with(handler, *exceptions):
try:
handler, cleanup = handler
except TypeError:
cleanup = lambda f, e: None
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except exceptions or Exception as e:
return handler(func, e)
finally:
cleanup(func, e)
return wrapper
return decorator
这仅捕获您指定的异常。如果您不指定任何内容,Exception
则会被捕获。此外,第一个参数可以是两个处理函数的元组(或其他序列);finally
第二个处理程序(如果给定)在子句中调用。从主处理程序返回的值作为函数调用的值返回。
现在,鉴于上述情况,您可以编写:
@handle_with(message, TypeError, ValueError)
def add(x, y):
return x + y
您也可以使用上下文管理器执行此操作:
from contextlib import contextmanager
@contextmanager
def handler(handler, *exceptions):
try:
handler, cleanup = handler
except TypeError:
cleanup = lambda e: None
try:
yield
except exceptions or Exception as e:
handler(e)
finally:
cleanup(e)
现在你可以写:
def message(e):
print "Exception", type(e).__name__
print str(e)
def add(x, y):
with handler(message, TypeError, ValueError):
return x + y
请注意,上下文管理器不知道它在哪个函数中(你可以找到它,sorta, using inspect
,虽然这是“魔法”,所以我没有这样做)所以它给你的信息不太有用。此外,上下文管理器不会让您有机会在处理程序中返回任何内容。