装饰器

装饰器函数的执行顺序是分为(被装饰函数)定义阶段和(被装饰函数)执行阶段的,装饰器函数在被装饰函数定义好后立即执行

  • 在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行
  • 在函数执行阶段:执行顺序由外而内,一层层执行
def war1(func):
    print("war1")
    def inner(*args, **kwargs):
        print("======war1 start=====")
        func(*args, **kwargs)    #inner
        print("======war1 end=====")
    return inner
 
def war2(func):
    print("war2")
    def inner(*args,**kwargs):
        print("======war2 start=====")
        func(*args,**kwargs)
        print("======war2 end=====")
    return inner
 
@war1
@war2
def f():
    print("****self****")
f()
  • 执行结果

在这里插入图片描述
那么为什么会是这样的顺序

看到这个执行结果,我们可能会疑惑,为什么先打印了war2 和war1呢?

首先要知道,装饰器函数在被装饰函数定义好后就立即执行了

我们去掉函数执行,只留下函数的定义,代码如下:

def war1(func):
    print("war1")
    def inner(*args, **kwargs):
        print("======war1 start=====")
        func(*args, **kwargs)    #inner
        print("======war1 end=====")
    return inner
 
def war2(func):
    print("war2")
    def inner(*args,**kwargs):
        print("======war2 start=====")
        func(*args,**kwargs)
        print("======war2 end=====")
    return inner
 
@war1
@war2
def f():
    print("****self****")

结果
在这里插入代码片
也就是说在 f 方法没有执行的时候,装饰器函数就执行了

此处我们需要先弄清楚,函数和函数调用的区别,f 是一个函数,它的值是函数本身, f( )是函数的调用,它的值是函数的执行结果

在被装饰函数定义阶段,也就是函数调用之前:

@war1
@war2
def f():
    print("****self****")

上面代码相当于执行

war1(war2(f))

在综合起来就是相当于执行了先打印war2war1,再执行函数war1(war2(f))
按照这样的顺序执行,层层包裹执行方式

war2-->war1--> war1-->war2-->f -->war2-->war1 

在这里插入图片描述
所以最终结果为
在这里插入图片描述

同理对于三个装饰器

在这里插入图片描述

三个装饰器对应两个函数

在这里插入图片描述

可以看到f2并没有用到装饰器

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • 装饰器实现乘法效果

def f(n):
    def out_wrapper(func):
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        return wrapper
    return out_wrapper

n=5
@f(n) #@f(n=5)或者@f(5)都是错的,会显示n未定义
def p(x):
    return x * n

p(4)

在这里插入图片描述
其实就是实现下面代码的效果

def f(n):
    def g(x):
        return n*x
    return g
f1=f(5)
f1(4)

法二:

def f(n):
    def warpper(func):
        def q23(*args, **kw):
            return func(*args, **kw)*n
        return q23
    return warpper
    
@f(n=1200)#或者n=1200,@f(n)
def p(x):
    return x
print(p(6))

在这里插入图片描述
法三:

from functools import partial


def f(func=None, *, n):
    if func is None:
        return partial(f, n=n)

    def wrapper(*args, **kwargs):
        return func(*args, **kwargs) * n

    return wrapper


@f(n=5)
def p(x):
    return x


p(4)

在这里插入图片描述

其实廖雪峰老师已经讲得很明白了,是我自己没有参悟透

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值