【问题标题】:wrapping class method in try / except using decorator在 try / 中包装类方法,除了使用装饰器
【发布时间】: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 转换为类中的方法,如果这样可以让事情变得更容易。

【问题讨论】:

    标签: python python-2.7 decorator python-decorators


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2014-01-14
      • 2020-01-11
      • 2018-06-21
      • 2011-06-26
      • 2014-12-31
      • 1970-01-01
      • 2021-08-07
      • 2014-12-29
      相关资源
      最近更新 更多