python 函数结果缓存一段时间的装饰器
把函数结果缓存一段时间,比如读取一个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 + d print(f10(1, 2, 3, 4))
print(f10(1, 2, 3, 4))
time.sleep(4)
print(f10(1, 2, 3, 4)) 运行结果是这样
可以发现只计算了两次,第一次是开始时候没有缓存所以要计算,第二次有缓存了就不计算,第三次因为超过了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 函数结果缓存一段时间的装饰器的更多相关文章
- 12、Python函数高级(命名空间、作用域、装饰器)
一.名称空间和作用域 1.命名空间(Namespace) 命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的. 命名空间提供了在项目中避免名字冲突的一种方法.各个命名空 ...
- Python函数名做参数,闭包,装饰器
简单讲解闭包的写法和应用,在这之前,先声明,你定义的任意一个函数都可以作为其他函数的参数.就像下面这段代码的参数func,接收的参数就是一个函数名,在函数体内部使用了func()调用执行函数. 请看下 ...
- python 全栈开发,Day12(函数的有用信息,带参数的装饰器,多个装饰器装饰一个函数)
函数的执行时,*打散.函数的定义时,*聚合. from functools import wraps def wrapper(f): # f = func1 @wraps(f) def inner(* ...
- Python学习(三):迭代器、生成器、装饰器、递归、算法、正则
1.迭代器 迭代器是访问集合的一种方式,迭代对象从集合的第一个元素开始访问,直到元素被访问结束,迭代器只能往前不能后退,最大的优点是不要求事先准备好整个迭代过程中的元素,这个特点使得它特别适合用于遍历 ...
- Python自动化面试必备 之 你真明白装饰器么?
Python自动化面试必备 之 你真明白装饰器么? 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多小白来讲,这个功能 有点绕 ...
- Python 第四篇:生成器、迭代器、装饰器、递归函数与正则表达式
一:生成器:Generator,可以理解为是一种一个函数产生一个迭代器,而迭代器里面的数据是可以通过for循环获取的,那么这个函数就是一个生成器,即生成器是有函数生成的,创建生成器使用()表示,比如g ...
- python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解
python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...
- python语法生成器、迭代器、闭包、装饰器总结
1.生成器 生成器的创建方法: (1)通过列表生成式创建 可以通过将列表生成式的[]改成() eg: # 列表生成式 L = [ x*2 for x in range(5)] # L = [0, 2, ...
- Python开发【第十四篇】装饰器
装饰器 什么是装饰器? 装饰器是一个函数,主要作用是用来给包装另一个函数或者类 包装的目的是不改变原函数名(或类名)的情况下改变或添加被包装对象的功能 函数装饰器 是指装饰器是一个函数,传入的是一 ...
随机推荐
- Python 读取数据
将一个文件夹下面的图像和对应的pts读进来,然后把pts文件里面的数据读入一个数组,然后画到图像上: # -*- coding:utf- -*- """ 测试数据样例 & ...
- spring+dubbo整合
创建公共接口或者project用到的一些bean.我这里就仅仅是创建了一个接口.project文件夹例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...
- 【oneday_onepage】——How to stretch the life of your SSD storage
How to stretch the life of your SSD storage July 18, 2013, 9:06 PM — Once a PC enthusiast's dream st ...
- 如何在ROS中使用PCL(2)
记录关于我们运行roslaunch openni_launch openni.launch 命令时生成的话题以及这些话题的数据类型便于后期的处理,只有知道它们的数据结构,才能很好的对数据进行处理,我 ...
- PCL采样一致性算法
在计算机视觉领域广泛的使用各种不同的采样一致性参数估计算法用于排除错误的样本,样本不同对应的应用不同,例如剔除错误的配准点对,分割出处在模型上的点集,PCL中以随机采样一致性算法(RANSAC)为核心 ...
- fastjson生成JSON字符串的时候出现$ref
fastjson生成JSON字符串的时候出现$ref 转载自:http://wuzhuti.cn/201426!826!05!130202.html 可以通过选项 DisableCircularRef ...
- webpack9--删除冗余的CSS
我们在写代码的时候可能有些CSS并没有用到,我们如何利用webpack将冗余的CSS清除掉呢? 可以使用 purifycss-webpack 达到该目的. 1.安装 purifycss-webpack ...
- Navi.Soft31.WinForm框架(含下载地址)
1概述 1.1应用场景 尽管互联网高速发展,互联网软件也随之越来越多,但桌面应用程序在某些领域中还是不可替代,如MIS,ERP,CRM等软件产品,同时,这类软件均包括一些通用的功能,如:与数据库操作, ...
- Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat 解决办法
问题描述 安装 Python的MySQL驱动时时出现这个错误: Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat 环境 ...
- Spring Boot Controller相应JSP页面 错误whitelabel error page
在学习SpringBoot显示JSP页面的时候出现了错误,Controller可以正常调用,但是JSP页面就是不能正常显示. whitelabel error page 解决:注释掉scope < ...