首页 技术 正文
技术 2022年11月6日
0 收藏 420 点赞 258 浏览 1782 个字

把函数结果缓存一段时间,比如读取一个mongodb,mongodb中的内容又在发生变化,如果从部署后,自始至终只去读一次那就感触不到变化了,如果每次调用一个函数就去读取那太频繁了耽误响应时间也加大了cpu负担,也不行。那就把结果缓存一段时间。

来一个缓存一段时间的装饰器。

class FunctionResultCacher:
logger = LogManager('FunctionResultChche').get_logger_and_add_handlers()
func_result_dict = {}
"""
{
(f1,(1,2,3,4)):(10,1532066199.739),
(f2,(5,6,7,8)):(26,1532066211.645),
}
""" @classmethod
def cached_function_result_for_a_time(cls, cache_time):
"""
函数的结果缓存一段时间装饰器
:param cache_time 缓存的时间
:type cache_time : float
""" def _cached_function_result_for_a_time(fun): @wraps(fun)
def __cached_function_result_for_a_time(*args, **kwargs):
if len(cls.func_result_dict) > 1024:
cls.func_result_dict.clear() key = cls._make_arguments_to_key(args, kwargs)
if (fun, key) in cls.func_result_dict and time.time() - cls.func_result_dict[(fun, key)][1] < cache_time:
return cls.func_result_dict[(fun, key)][0]
else:
result = fun(*args, **kwargs)
cls.func_result_dict[(fun, key)] = (result, time.time())
cls.logger.debug('函数 [{}] 此次不使用缓存'.format(fun.__name__))
return result return __cached_function_result_for_a_time return _cached_function_result_for_a_time @staticmethod
def _make_arguments_to_key(args, kwds):
key = args
if kwds:
sorted_items = sorted(kwds.items())
for item in sorted_items:
key += item
return key

测试下:

@FunctionResultCacher.cached_function_result_for_a_time(3)
def f10(a, b, c=3, d=4):
print('计算中。。。')
return a + b + c + dprint(f10(1, 2, 3, 4))
print(f10(1, 2, 3, 4))
time.sleep(4)
print(f10(1, 2, 3, 4))运行结果是这样python 函数结果缓存一段时间的装饰器

可以发现只计算了两次,第一次是开始时候没有缓存所以要计算,第二次有缓存了就不计算,第三次因为超过了3秒就不使用缓存了,所以要计算。

需要注意一点的是用字典做的缓存,如果函数的结果非常大,部署后一直运行,一段时间后会占一大块内存,所以设置了1024个缓存结果,否则就清除字典。如果函数没有入参或者入参都是一样的那就没事,如果入参不一样且函数返回结果超长是一个几百万长度的字符串,那就用此装饰器时候要小心点。
把if len(cls.func_result_dict) > 1024:     改为if sys.getsizeof(cls.func_result_dict) > 100 * 1000 * 1000,则是直接判断内存。
此装饰器可以装饰在函数上,当然也可以装饰在方法上了。因为 *args **kwargs代表了所有参数,self只是其中的一个特殊参数而已,所以可以装饰在方法上。functools模块有个lru_cache装饰器,是缓存指定次数的装饰器,这个是缓存指定时间的。

    					
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,034
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,149
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,782
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,863