透明链(组合)装饰器

时间:2018-01-17 21:15:38

标签: python decorator python-decorators

我知道这不是装饰者的意图但是......

我有装饰器来保存各种功能,包括xlsx,csv,其他

我想做的是

@save_xlsx
@save_csv
def whatever_function():

并将一个文件保存在.xlsx中,另一个文件保存在.csv中,两者都使用whatever_function()的相同输出。我还希望能够在其他函数上只使用一个装饰器。

或者这可能不是正确的做法?

1 个答案:

答案 0 :(得分:3)

这有点让我想起了monad。无论如何,你可以制作一个透明的通用日志装饰器:

def log(callback):
    def logger(fn):
        def logwrapper(*args, **kwargs):
            value = fn(*args, **kwargs)
            callback(value)
            return value
        return logwrapper
    return logger

csv_callback = lambda x: print('writing {} to a csv file'.format(x))
xlsx_callback = lambda x: print('writing {} to an xlsx file'.format(x))

@log(csv_callback)
@log(xlsx_callback)
def test(a, b):
    return a + b

In [2]: test(1, 2)
writing 3 to an xlsx file
writing 3 to a csv file
Out[2]: 3

In [3]: test(2, 3)
writing 5 to an xlsx file
writing 5 to a csv file
Out[3]: 5

您也可以将几个回调传递到记录器中以避免过度嵌套

def log(*callbacks):
    def logger(fn):
        def logwrapper(*args, **kwargs):
            value = fn(*args, **kwargs)
            for callback in callbacks:
                callback(value)
            return value
        return logwrapper
    return logger

@log(csv_callback, xlsx_callback)
def test(a, b):
    return a + b