把函数结果缓存一段时间,比如读取一个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),}"""@classmethoddef 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 resultreturn __cached_function_result_for_a_timereturn _cached_function_result_for_a_time@staticmethoddef _make_arguments_to_key(args, kwds):key = argsif kwds:sorted_items = sorted(kwds.items())for item in sorted_items:key += itemreturn 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装饰器,是缓存指定次数的装饰器,这个是缓存指定时间的。

转载于:https://www.cnblogs.com/ydf0509/p/9341365.html

python 函数结果缓存一段时间的装饰器相关推荐

  1. python timer 死掉_Python timer定时器两种常用方法解析 Python中如何在一段时间后停止程序...

    如何调用定时器 python 如何在python里面for循环中放了一个定时函数,当定# 我的构想程序效果 for Img in ImgArray: timer = threading.Timer(1 ...

  2. python grpc unary call错误_python的黑魔法-装饰器

    python的装饰器 装饰器 简单的来说就是函数的函数,在执行目标函数时,先执行装饰器函数,很像HOOk 简单的装饰器 实现一个打印日志的装饰器 def myLogger(func):def wrap ...

  3. python基础知识7——迭代器,生成器,装饰器

    迭代器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器 ...

  4. Python:从requests请求重试到万能重试装饰器

    今天来介绍下Python中从requests请求重试到万能重试装饰器. 从requests请求重试到万能重试装饰器 重试,在编写代码的过程中,是一个很常见的需求. 比如: 请求重试(例如:超时) 文件 ...

  5. python程序会监控错误的语句_python装饰器实现对异常代码出现进行自动监控

    异常,不应该存在,但是我们有时候会遇到这样的情况,比如我们监控服务器的时候,每一秒去采集一次信息,那么有一秒没有采集到我们想要的信息,但是下一秒采集到了, 而后每次的采集都能采集到,就那么一次采集不到 ...

  6. python面试充电(3)面向对象、装饰器、包与模块

    面向对象 关于面向对象解读,参考知乎一个回答https://www.zhihu.com/question/20275578/answer/26577791 python里面类其本质就是为了封装.把对象 ...

  7. python 递归函数_让你Python到很爽的加速递归函数的装饰器

    Python技巧--好用的一个装饰器 今天我们会讲到一个装饰器. 注记:链接"装饰器"指向廖雪峰老师的Python3教程中的装饰器教程.可以在这里快速了解什么是装饰器. `@fun ...

  8. python递归函数的使用方法_让你Python到很爽的加速递归函数的装饰器

    Python技巧--好用的一个装饰器 今天我们会讲到一个装饰器. 注记:链接"装饰器"指向廖雪峰老师的Python3教程中的装饰器教程.可以在这里快速了解什么是装饰器. @func ...

  9. 函数嵌套,关键字,闭包和装饰器

    函数嵌套 概念:在一个函数的内部定义另一个函数 为什么要有函数的嵌套定义: 1)函数fn2想直接使用fn1函数的局部变量,可以将fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量 2) ...

最新文章

  1. java基础学习(2)-java基本数据类型
  2. 图像处理之霍夫变换(直线检測算法)
  3. Codeforces936C. Lock Puzzle
  4. Spring启动时的Spring社交示例,或者我如何不再担心和喜欢自动配置
  5. linux mysql服务器安装_Linux服务器MySQL安装
  6. 【转】有限状态机用法教程
  7. 多线程 转账_Java多线程编程基础三(原子性,可见性和有序性)
  8. Google发转码工具 可将安卓程序转至iOS
  9. Direct3D顶点结构使用总结
  10. MinGW —— Minimalist GNU for Windows、Cygwin —— Windows 下的类 unix 系统
  11. csdn发布文章无法查看
  12. matlab对有周期性噪声的图像去噪,数字图像中去除周期性噪声研究.doc
  13. html修改鼠标手势,css设置鼠标手势的方法
  14. hz和分贝怎么转换_分贝换算(db换算公式)
  15. 51单片机引脚内部电路
  16. larval中redis的用法
  17. Java: 实训三 类与对象、继承
  18. python pip install fitter 失败解决方案
  19. 举例在移动HTML5 UI框架有那些
  20. 经典不等式链的一些拓展理解

热门文章

  1. 使用VS 2019,.NET Core 3和Web API创建ASP.NET Core Blazor CRUD应用程序
  2. php ip操作,ip操作 · PHP 个人常用知识总结 · 看云
  3. starima与arima 预测_38-一些预测模型与方法简介(ARIMA、指数平滑等)
  4. python apache_Windows 配置 Apache Python CGI
  5. cublas matlab,Check failed: status == CUBLAS_STATUS_SUCCESS (11 vs. 0) CUBLAS_STATUS_MAPPING_ERROR
  6. ElasticSearch启动报错,报ERROR: [3] bootstrap checks failed
  7. 如何在SQL Server中的SELECT TOP 中使用变量
  8. 新浪sae部署html,利用新浪sae搭建discuz x2论坛
  9. linux7重装linux6,CentOS6远程重装7过程
  10. python语言程序的特点_《Python语言程序设计》 —1.1.3 Python的特点及应用领域...