在 try / 中包装类方法,除了使用装饰器
Posted
技术标签:
【中文标题】在 try / 中包装类方法,除了使用装饰器【英文标题】:wrapping class method in try / except using decorator 【发布时间】:2014-06-06 18:59:35 【问题描述】:我有一个通用功能,可以将有关异常的信息发送到应用程序日志。
我在类的方法中使用exception_handler
函数。传递给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
转换为类中的方法,如果这样可以让事情变得更容易。
【问题讨论】:
【参考方案1】:这样的装饰器就是:
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
。
【讨论】:
谢谢 Martijn。看起来不错,除了我如何将 self.log 传递给 handle_exceptions?它没有可见的“自我”。 @RoyHB:啊,我错过了你在那里使用self.log
,我很抱歉。调整为使用args[0]
,但您也可以使wrapper()
采用def wrapper(self, *args, **kw)
的显式self
参数,并使用return f(self, *args, **kw)
。
底部不应该有return wrapper
吗?
@EthanBierlein:确实应该有。【参考方案2】:
感谢 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
【讨论】:
以上是关于在 try / 中包装类方法,除了使用装饰器的主要内容,如果未能解决你的问题,请参考以下文章