python多个装饰器的执行顺序

Posted lishanlu136

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python多个装饰器的执行顺序相关的知识,希望对你有一定的参考价值。

当python函数被多个装饰器装饰时,装饰顺序和执行顺序是怎样的,我用一个简单的例子来说明

def decorator_a(func):
    print('Get in decorator_a')

    def inner_a(*args, **kwargs):
        print('Get in inner_a')
        return func(*args, **kwargs)
    return inner_a


def decorator_b(func):
    print('Get in decorator_b')

    def inner_b(*args, **kwargs):
        print('Get in inner_b')
        return func(*args, **kwargs)

    return inner_b


@decorator_b
@decorator_a
def f(x):
    print('Get in f')
    return x * 2


if __name__ == '__main__':
    a = f(2)
    print("a =",a)

执行文件得到的结果是:

Get in decorator_a
Get in decorator_b
Get in inner_b
Get in inner_a
Get in f
a = 4

我们来分析一下,为什么会是这样的顺序
首先注释掉代码的执行部分,即a = f(2),执行文件,只打印两行:

Get in decorator_a
Get in decorator_b

这说明装饰器函数在被装饰函数定义好后就立即执行。而且执行顺序是由下到上开始装饰。调用decorator_a时,f被装饰成inner_a,调用decorator_b时,f被装饰成inner_b。
通过在最后执行:print(f),可验证。


def decorator_a(func):
    ...
    return inner_a


def decorator_b(func):
    ...
    return inner_b


@decorator_b
@decorator_a
def f(x):
    print('Get in f')
    return x * 2


if __name__ == '__main__':
    print(f)

执行结果为:

Get in decorator_a
Get in decorator_b
<function decorator_b.<locals>.inner_b at 0x0000019C6FC62820>

所以当调用函数执行时,a=f(2),f已经变成了inner_b,而inner_b中return的func,实则为inner_a,inner_a中return的func才是最终的f。
所以最后的调用顺序为
inner_b —>inner_a—>f
执行部分打印的结果就为:

Get in inner_b
Get in inner_a
Get in f
a = 4

总结:
多个装饰器装饰函数时,规律是从下到上包裹(装饰)函数,然后从上到下执行。

以上是关于python多个装饰器的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

python多个装饰器的执行顺序

python 中多个装饰器的执行顺序

python 多个装饰器的调用顺序

Python多个装饰器的顺序 转载

python 多个装饰器的调用顺序分析

python3-多装饰器的执行顺序