做一个cache装饰器,实现过期被清除

功能

简化设计,函数的形参定于不包含可变位置参数,可变参数可以不考虑缓存满了之后的换出问题

数据类型选择

缓存的应用场景,是有数据需要频繁查询,且每次查询都需要大量技术按或者等待事件之后才能返回结果的情况,使用缓存来提高查询速度,用空间换时间

cache应该选择用什么数据结构

便于查询,且能快速找到的数据结构,每次查询的时候,输入一致,就应该得到相同结果的(顺序一致),所以字典最合适,通过一个key对应一个value

key的存储

可变类型先不作为函数参数hash会有问题
  • key必须是hash值
  • key能够接受位置参数和关键字传参
  • 位置参数被收集在tuple中,本身就是顺序
  • 关键字参数被收集到一个字典中,本身无序,会有一个问题传参的顺序未必是字典中保存的循序,OrderedDict(有序字典可以)也可以用tuple保存字典的key,item

算是相同的key

def add:
	return x+y

add(4,5)
add(4,y=5)
add(y=5,x=4)
add(x=4.y=5)

key的要求

有序key是所有实参组合而成,而且最好要作为key的key一定要可以hash的 inspect模块可以获取函数签名,取parameters,这是一个有序字典,会保存所有参数信息 构建一个字典params_dist,按照位置顺序从安然公司中一次对应参数名和传入的参数,组成看v对存入params_dict中 kwargs所有值update到params_dict中

实现

from functools import wraps
import time
import inspect
import datetime

def n_cache(fn):
    local_cache = {}
    @wraps(fn)
    def wrapper(*args,**kwargs):
        print(args,kwargs)
        key_dict = {}
        sig=inspect.signature(fn)
        od = sig.parameters #有序字典
        param_list = list(od.keys())
        	
        #位置参数
        for i,x in enumerate(args):
            k=param_list[i]
            key_dict[k]= x
			
        key_dict.update(kwargs)
        print(key_dict.items())
        #缺省值
        print(od.keys(),"def")
        for k in od.keys():
            if k not in key_dict.keys():
                key_dict[k]=od[k].default
        
        key=tuple(sorted(key_dict.items()))
        print(tuple(sorted(key_dict.items())))
	#for k,v in kwargs.items():
	#	key_dict[k]=v
        if key not in local_cache.keys():
            res = fn(*args,**kwargs)
            local_cache[key]=res
        print(local_cache)
        return local_cache[key]
    return wrapper

def logger(fn):
    @wraps(fn)
    def wrapper(*args,**kwargs):
        start = datetime.datetime.now()
        res = fn(*args,**kwargs)
        delte = datetime.datetime.now()-start
        delte = delte.total_seconds()
        print("执行时间",delte)
        return res
    return wrapper
@logger
@n_cache
def add(x,y=1):
    time.sleep(3)
    return x+y

缓存过期功能

from functools import wraps
import time
import inspect
import datetime

def n_cache(fn):
    local_cache = {}
    @wraps(fn)
    def wrapper(*args,**kwargs):
        delkey = []
        print(local_cache)
        for k,(v,ts) in local_cache.items():
            if datetime.datetime.now().timestamp()-ts >5:  #5秒过期
                delkey.append(k)
        for k in delkey:
            local_cache.pop(k)
        
        print(args,kwargs)
        key_dict = {}
        sig=inspect.signature(fn)
        od = sig.parameters #有序字典
        param_list = list(od.keys())
        	
        #位置参数
        for i,x in enumerate(args):
            k=param_list[i]
            key_dict[k]= x
			
        key_dict.update(kwargs)
        print(key_dict.items())
        #缺省值
        print(od.keys(),"def")
        for k in od.keys():
            if k not in key_dict.keys():
                key_dict[k]=od[k].default
        
        key=tuple(sorted(key_dict.items()))
        print(tuple(sorted(key_dict.items())))
	#for k,v in kwargs.items():
	#	key_dict[k]=v
        if key not in local_cache.keys():
            res = fn(*args,**kwargs),datetime.datetime.now().timestamp()
            local_cache[key]=res
            
        print(local_cache)
        return local_cache[key][0]
    return wrapper

def logger(fn):
    @wraps(fn)
    def wrapper(*args,**kwargs):
        start = datetime.datetime.now()
        res = fn(*args,**kwargs)
        delte = datetime.datetime.now()-start
        delte = delte.total_seconds()
        print("执行时间",delte)
        return res
    return wrapper
@logger
@n_cache
def add(x,y=1):
    time.sleep(3)
    return x+y

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值