使用装饰器在try/except中包装类方法
我有一个通用的函数,用来把异常信息发送到应用程序的日志里。我在类的方法中使用了exception_handler
这个函数。传递给exception_handler
并由它调用的应用日志处理器,会创建一个JSON字符串,这个字符串就是实际发送到日志文件的内容。这个过程一切正常。
def exception_handler(log, terminate=False):
exc_type, exc_value, exc_tb = sys.exc_info()
filename, line_num, func_name, text = traceback.extract_tb(exc_tb)[-1]
log.error('{0} Thrown from module: {1} in {2} at line: {3} ({4})'.format(exc_value, filename, func_name, line_num, text))
del (filename, line_num, func_name, text)
if terminate:
sys.exit()
我用它的方式是这样的:(一个超级简单的例子)
from utils import exception_handler
class Demo1(object):
def __init__(self):
self.log = {a class that implements the application log}
def demo(self, name):
try:
print(name)
except Exception:
exception_handler(self.log, True)
我想把exception_handler
改造成一个装饰器,用于很多方法,也就是说:
@handle_exceptions
def func1(self, name)
{some code that gets wrapped in a try / except by the decorator}
我看过很多关于装饰器的文章,但还没弄明白怎么实现我想要的功能。我需要传递一个活动日志对象的引用,还要能传递0个或多个参数给被包装的函数。如果把exception_handler
转换成类中的一个方法,那样可能会更简单。
2 个回答
4
感谢Martijn给我指明了方向。虽然我没能让他推荐的解决方案奏效,但在他的例子基础上多找了一下,结果发现以下方法很好用:
def handle_exceptions(fn):
from functools import wraps
@wraps(fn)
def wrapper(self, *args, **kw):
try:
return fn(self, *args, **kw)
except Exception:
exception_handler(self.log)
return wrapper
16
这个装饰器其实就是这么简单:
def handle_exceptions(f):
def wrapper(*args, **kw):
try:
return f(*args, **kw)
except Exception:
self = args[0]
exception_handler(self.log, True)
return wrapper
这个装饰器的作用就是在一个try
块里面调用被装饰的函数。
这个装饰器只能用在方法上,因为它假设第一个参数是self
。