标签:调用 creat duration cond size pop wrapper pos time
from functools import wraps
import time,inspect,datetime
def m_cache(duration):
def _cache(fn):
local_cache={}
@wraps(fn)
def wrapper(*args,**kwargs):
def clear_expire_keys(cache):
expire_keys=[] # 记录过期key
for k,(_,timestamp) in cache.items(): # 寻找过期key
if datetime.datetime.now().timestamp()-timestamp > duration:
expire_keys.append(k)
for k in expire_keys: # 清除过期key
local_cache.pop(k)
clear_expire_keys(local_cache)
def make_key():
key_dict={}
sig=inspect.signature(fn)
od=sig.parameters
# param_list=[key for key in od.keys()]
param_list=list(od.keys()) # inspect获取的参数列表
# positional arguments
for index,v in enumerate(args):
# print(index,v)
k=param_list[index]
key_dict[k]=v
# keywords arguments
for k,v in kwargs.items():
key_dict[k]=v
# key_dict.update(kwargs)
for k in od.keys(): # 对缺省参数的处理,置于key生成前
if k not in key_dict.keys():
key_dict[k]=od[k].default
return tuple(sorted(key_dict.items()))
key=make_key()
print(key)
if key not in local_cache.keys():
ret=fn(*args,**kwargs)
local_cache[key]=ret,datetime.datetime.now().timestamp()
return local_cache[key][0]
return wrapper
return _cache
def logger(fn):
@wraps(fn)
def wrapper(*args,**kwargs):
start=datetime.datetime.now()
ret=fn(*args,**kwargs)
delta=(datetime.datetime.now()-start).total_seconds()
print(delta)
return ret
return wrapper
@logger
@m_cache(3)
def dix(x,y=6,z=3):
time.sleep(z)
print(‘x: {}\ty: {}‘.format(x,y))
print(‘\n‘*3)
return x+y
print(dix(7))
print(dix(7,y=6))
print(dix(x=7,y=6))
print(dix(y=6,x=7))
print(dix(4,8,y=6,x=7)) # 不符合原函数的定义,但是形成key一样,直接从local_cache取结果,避免了函数的的真正执行,故未报错
time.sleep(4)
print(dix(7))
print(dix(7,y=6))
print(dix(x=7,y=6))
print(dix(y=6,x=7))
print(dix(4,8,y=6,x=7))
缓存过期:
是dict中某个key过期,可以对每一个key单独设置过期时间,也可以对key设定统一过期时间
上面的装饰器增加一个参数,形成带参装饰器
@m_cache(3)代表key生存3s后过期
带参装饰器等于在原来的装饰器外面再嵌套一层
清除时机:
value的设计:
标签:调用 creat duration cond size pop wrapper pos time
原文地址:https://www.cnblogs.com/dissipate/p/13657751.html