2014-04-22 37 views
4

我有一个通用函数,用于向应用程序日志发送有关异常的信息。 我使用类的方法中的exception_handler函数。传入exception_handler并由exception_handler调用的应用程序日志处理程序会创建一个JSON字符串,该字符串实际上会被发送到日志文件。这一切工作正常。在try /使用装饰器除外包装类方法

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() 

我使用它作为如下:(a超简化的示例)

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转换为类中的方法,如果这样做更容易。

回答

8

这样的装饰,简直是:

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

+0

感谢马亭。这看起来不错,但我如何将self.log传入handle_exceptions?没有“自我”可见。 – RoyHB

+0

@RoyHB:啊,我错过了你在那里使用了'self.log',我的歉意。调整为使用'args [0]',但是你也可以用'def wrapper(self,* args,** kw)'使'wrapper()'得到一个明确的'self'参数,并使用'return f(self ,* args,** kw)'。 –

+0

不应该在底部有一个'返回包装器'? –

0

感谢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