多个装饰器叠加

一层装饰器的情况分析

import time

def timmer(func):
    def wrapper(*args,**kwargs):
        start=time.time()
        func(*args,**kwargs)
        end=time.time()
        print('process run time is %s'%(end-start))
    return wrapper

@timmer
def index():
    print('from index')
    time.sleep(2)

index()

分析timmer装饰器:

  1. @timmer首先运行timmer,并把index函数当做参数传给timmer(index),
  2. 返回wrapper函数并赋值给index,此时的index已经不是最开始的index函数了,
  3. 这时候指向的是wrapper函数,并把wrapper函数的作用域变为全局了。
  4. 上面都是加载的步骤,index()表示运行wrapper(),于是进入wrapper函数内执行代码
    这是一层装饰器的加载和运行步骤

两层装饰器的情况分析

定义两个装饰函数,一个计算函数运行时间,一个是认证功能

import time
def auth(engine='file'):
    def outter(func):
        def wrapper1(*args,**kwargs):
            if engine=='file':
                input_name = input('name>>>')
                input_passwd = input('password>>>')
                if input_passwd == 'abc' and input_name == 'zz':
                    print('login successful')
                    res = func(*args, **kwargs)
                elif engine == 'mysql':
                    print('基于mysql的认证')
                else:
                    print('未识别的认证源')
            return res
        return wrapper1
    return outter

def timmer(func):
    def wrapper2(*args,**kwargs):
        start=time.time()
        func(*args,**kwargs)
        end=time.time()
        print('process run time is %s'%(end-start))
    return wrapper2

@auth(engine='file')
@timmer
def index():
    print('this is from index')
    time.sleep(2)

index()

当一个被装饰的对象同时叠加多个装饰器时
装饰器的加载顺序是:自下而上
装饰器内wrapper函数的执行顺序是:自上而下

所以index函数首先被timmer装饰,

  1. @timmer wrapper2=timmer(index) index=wrapper2
  2. @auth(engine='file') outter=auth(engine='file')-->@outter wrapper1=outter(index-->wrapper2)
  3. 所以最后index()执行时,其实是执行wrapper1函数,而wrapper1里面的func函数指向index,这个index函数指向wrapper2函数
  4. 所以在auth函数里面等认证功能执行完毕后,会跳到timmer函数里面执行wrapper2函数,
  5. 在timmer函数里的func指向index函数,该函数是最开始的index函数,也就是被装饰的函数
  6. 在timmer函数里会执行最开始的index函数,执行完毕返回到wrapper2,等wrapper2函数执行结束,会返回到wrapper1函数
  7. wrapper1函数执行完毕,程序结束
原文地址:https://www.cnblogs.com/zuanzuan/p/9720551.html