wrap 缓存。。。

 

from functools import wraps
import inspect 
import datetime
def  cache(exp=0): #超时0 也就是没有超时时间
    def _cache(fn):
        c = {} #把结果存放到cache里面,用来存储我们的缓存
        @wraps(fn)
        def wrap(*args,**kwargs):
            #1 key 如何封装args kwargs
            print (args)
            print (kwargs)
            key=[ ] #初始化是空值

            names=set() #name 需要加入,args 和kwargs的name 要做修改,names 作为key避免重复用set()

            params = inspect.signature(fn).parameters #获取所有的参数,获取后第一步,参数列表
            #args 操作
            for i ,arg in enumerate(args): #args是元祖 arg 是value,那么name是什么?args 是位置参数
                #value 和params  取出的值是一样的。 args 是位置参数,所以他的顺序和params 顺序是一致的
                name = list(params.keys())[i]#获取所有的key 通过下标i去访问,返回x或y
                # ,name是我们的key
                key.append((name,arg)) #把元祖丢进去 key====>[(x,1),(y,2)]

                names.add(name) #把上面的name丢进去

            #kwargs操作
            #for k,v in kwargs.items():
             #   key.append((k,v))
            #更简单办法
            key.extend(kwargs.items()) #key 已经封装了
            names.update(kwargs.keys()) #kwargs的names更新了
            for k,v in params.items(): #之前的params的list params是整个函数的参数列表
                #如何获取默认参数,
                #***如果定义函数的时候,有默认参数,在传参的时候没有传这个默认参数,我们就拿不到它
                #params是整个函数的参数列表
                #判断params里不在names里的 就是默认参数
                if k not in names:
                    key.append((k,v.default))
            #排序 key是列表,列表有个方法key.sort、  sort参数有个key用于传fan,x就是指key里面每个迭代对象
            #x 可能是[(x,1),(y,2)]里面的(x,1) 或 (y,2)元祖,按照每个列表里面每一个元素的第一个排序,也就是key排序
            key.sort(key=lambda  x:x[0])
            #key 排序后进行封装,用&  join  列表解释式做
            key = '&'.join([ f'{name}={arg}'for name,arg in key]) #for name,args in key j解构
            print (key)
            #命中监测
            if key in c.keys():
                # 超时监测
                #如何判断一组key 什么时候执行过呢  
                #key &ts=2222233,还有一种,
                #key=(key,timestamp):values 用这个  用参数解构
                ret,timestamp =c[key] #拿到结果里面 有timestap 接收
                if exp==0 or datetime.datetime.now().timestamp() - timestamp< exp: #满足命中缓存的添加的输出结果
                    print(f'命中缓存:{key}:{args},{kwargs}')
                    return c[key]
            #2 超时监测
            #最后拿到结果  ret = fn(*args,**kwargs)
            ret = fn(*args,**kwargs)
            print('缓存未命中')
            c[key] = (ret,datetime.datetime.now().timestamp()) #元祖 
            return  ret
        return  wrap
    return _cache

 

posted @ 2018-12-17 23:34  Tom-Li  阅读(248)  评论(0编辑  收藏  举报