装饰器的叠加使用

装饰器得加使用原则

装饰器叠加使用,按照先里后外,先下后上的原则进行装饰。
让我们从实例中来分析
例两个装饰器out和logger

import datetime
from inspect import signature
from functools import wraps
#测试运行时长
def out(fn1):
    def inner(*args,**kwargs):#inner('7',8)
        start = datetime.datetime.now()
        ret = fn1(*args,**kwargs)#此处fn1('7',8) 为add最初代表的函数体
        delt = (datetime.datetime.now() -start).total_seconds()
        return ret
    return inner
#判断参数类型
def logger(fn):
    def wra(*args,**kwargs):#add('7',8) = wra('7',8)
        di={}
        param = signature(fn).parameters#此处fn为inner。
        di.update(zip(param.keys(),args),**kwargs)
        di.update(((k,v.default) for k in param.keys()-di.keys()))
        for k,v in di.items():
            if param[k].annotation != inspect._empty and not isinstance(v,param[k].annotation):
                print( "ErrorType")
        ret = fn(*args,**kwargs)#此处fn为inner。fn('7',8) = inner('7',8)
        return ret
    return wra

@out  #add = wra =  out(wra) = inner 
@logger  #add = logger(add) = wra
def add(x:str,y:int):
    return x+str(y)

按装饰原则
在装饰过程中,第一次logger先装饰,add = logger(add) = wra,logger中的fn为add最初代表的那个函数体
第二次out装饰,add = wra = out(wra) = inner ,out中的fn1位wra函数。所以最后调用add就相当于调用wra。
调用add函数—add(‘7’,8)的执行过程:
add(‘7’,8) = inner(‘7’,8)
执行inner函数:

def out(fn1):
    def inner(*args,**kwargs):#iadd('7',8) = inner('7',8)
        start = datetime.datetime.now()
        ret = fn1(*args,**kwargs)#此处fn1('7',8) = wra('7',8)
        delt = (datetime.datetime.now() -start).total_seconds()
        return ret
    return inner

运行到

ret = fn1(*args,**kwargs)#此处fn1('7',8) = wra('7',8)

执行wra函数

def wra(*args,**kwargs):#wra('7',8)
        di={}
        param = signature(fn).parameters#此处fn为add最初所表示的那个函数体
        di.update(zip(param.keys(),args),**kwargs)
        di.update(((k,v.default) for k in param.keys()-di.keys()))
        for k,v in di.items():
            if param[k].annotation != inspect._empty and not isinstance(v,param[k].annotation):
                print( "ErrorType")
        ret = fn(*args,**kwargs)#此处fn为add最初所表示的那个函数体
        return ret

运行到

 ret = fn(*args,**kwargs)#此处fn为add最初所表示的那个函数体

执行add最初表示的函数体

def add(x:str,y:int):
  return x+str(y)

然后 ret 接住add函数的返回值,wra函数返回ret, 因为wra = fn1,所以 ret 被inner函数里的ret接住,最后inner函数返回ret,函数调用结束。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值