Python学习之路-----装饰器(2)

多个装饰器的执行顺序

      在上一篇的博客中已经说明了装饰器自身的执行时机是在python解释器第一次读到@符号的时候执行的,这个根据现象是可以推测出来的,再结合装饰器的本质以及闭包也能够完全地理解这个知识点。那么当多个装饰器修饰一个函数时,执行顺序又是怎样的呢?看下面的代码

#coding=utf-8

def f1(func):
    print('in f1')
    def f1_inner():
        print('in f1_inner')
        func()
    return f1_inner


def f2(func):
    print('in f2')
    def f2_inner():
        print('in f2_inner')
        func()
    return f2_inner


@f1
@f2
def f():
    print('in f')

if __name__ == '__main__':
    pass
    #f()


结果:
in f2
in f1

    在上面的这个例子中装饰器f1和f2都是用来修饰函数f的,且顺序时f1在前f2在后。没有调用函数f,得到的打印结果如上。原因是:装饰器是用来修饰函数的,当python解释器读到@f1时发现下面的不是函数,而是另一个装饰器f2,因此才优先执行了f2,当f2执行完后,f2返回的才是一个函数的引用,因此才返回来执行f1。因此得出结论:装饰器本身的执行顺序和修饰顺序相反

    那么加上函数调用后结果又是怎样的呢?

    

#coding=utf-8

def f1(func):
    print('in f1')
    def f1_inner():
        print('in f1_inner')
        func()
    return f1_inner


def f2(func):
    print('in f2')
    def f2_inner():
        print('in f2_inner')
        func()
    return f2_inner


@f1
@f2
def f():
    print('in f')

if __name__ == '__main__':
    #pass
    f()



结果:

in f2
in f1
in f1_inner
in f2_inner
in f

      分析一下为什么是这个结果:如果上面的例子没问题的话,前两行的结果是毋庸置疑的。然后我们把装饰器哪里那里的三行代码加个注释,如下:

@f1   #f = f1(f)
@f2   #f = f2(f)
def f():
    print('in f')

这个换成闭包的 调用语句,因为装饰器f2比f1更近修饰函数f,因此函数f第一次返回的是f2中f2_inner的引用,然后才是f1中f1_inner函数的引用,最后才是函数f本身。由此得出:在多个装饰器修饰一个函数时,执行顺序是由内层装饰器向外侧开始的,最后才是被修饰的函数,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值