使用python中的多个装饰器从每个装饰器执行原始功能

时间:2017-09-21 22:17:53

标签: python python-3.6 python-decorators aiohttp

以下是我尝试做的简单示例。功能' print_number'下面是由2个装饰者包裹的。

def another_decorator(function):
    def wrapper(*arg, **kwargs):
        ret = function(*arg, **kwargs)
        print(ret, "executed from another_decorator")
    return wrapper

def test_decorator(function):
    def wrapper(*arg, **kwargs):
        ret = function(*arg, **kwargs)
        print(ret, "executed from test_decorator")
    return wrapper

@another_decorator
@test_decorator
def print_number(num):
    return num
x = print_number(222)
print(x)

以上返回

222 executed from test_decorator
None executed from another_decorator
None

如您所见,只有test_decorator能够执行包装的print_number函数。在another_decorator中完全跳过了对此函数的调用。 关于我为什么需要这个的一些背景。我有一些代码,我用多个装饰器包装一个主异步函数,我需要每个装饰器调用异步函数。每个装饰器做一些初步工作以传递给被调用的异步函数,其中创建aiohttp会话并使用ensure_future调度协程。 是否有方法或可能的程序从每个装饰者调用包装函数'函数?

1 个答案:

答案 0 :(得分:1)

你需要在你的装饰器中实际返回..。而且函数只是python中的对象所以给你的包装函数一个属性" original"

def another_decorator(function):
    def wrapper(*arg, **kwargs):
        ret = function(*arg, **kwargs)
        print(ret, "executed from another_decorator")
        return ret
    wrapper.original = getattr(function,"original",function)
    return wrapper

def test_decorator(function):
    def wrapper(*arg, **kwargs):
        ret = function(*arg, **kwargs)
        print(ret, "executed from test_decorator")
        return ret
    wrapper.original = getattr(function,"original",function)
    return wrapper