大蟒蛇python教程共享Python 如何手动编写一个自己的LRU缓存装饰器的方法实现

lru缓存算法,指的是近期最少使用算法,大体逻辑就是淘汰最长时间没有用的那个缓存,这里我们使用有序字典,来实现自己的lru缓存算法,并将其包装成一个装饰器。

1、首先创建一个my_cache.py文件 编写自己我们自己的lru缓存算法,代码如下:

  import time  from collections import ordereddict     '''  基于lru,近期最少用缓存算法写的装饰器。  '''        class lrucachedict:      def __init__(self, max_size=1024, expiration=60):          self.max_size = max_size          self.expiration = expiration             self._cache = {}          self._access_records = ordereddict()  # 记录访问时间          self._expire_records = ordereddict()  # 记录失效时间         def __setitem__(self, key, value):  # 设置缓存          now = int(time.time())          self.__delete__(key)  # 删除原有使用该key的所有缓存             self._cache[key] = value          self._access_records = now  # 设置访问时间          self._expire_records = now + self.expiration  # 设置过期时间          self.cleanup()         def __getitem__(self, key):  # 更新缓存          now = int(time.time())          del self._access_records[key]  # 删除原有的访问时按          self._access_records[key] = now          self.cleanup()         def __contains__(self, key):  # 这个是字典默认调用key的方法          self.cleanup()          return key in self._cache         def __delete__(self, key):          if key in self._cache:              del self._cache[key]  # 删除缓存              del self._access_records[key]  # 删除访问时间              del self._expire_records[key]  # 删除过期时间         def cleanup(self):  # 用于去掉无效(超过大小)和过期的缓存          if self._expire_records is none:              return none             pending_delete_keys = []          now = int(time.time())          for k, v in self._expire_records.items():  # 判断缓存是否失效              if v < now:                  pending_delete_keys.append(k)             for del_k in pending_delete_keys:              self.__delete__(del_k)             while len(self._cache) > self.max_size:  # 判断缓存是否超过长度              for k in self._access_records.keys():  # lru 是在这里实现的,如果缓存用的最少,那么它存入在有序字典中的位置也就最前                  self.__delete__(k)                  break  

代码逻辑其实很简单,上面的注释已经很详细了,不懂的话多看几次。这里实现lru逻辑的其实是有序字典ordereddict,你最先存入的值就会存在字典的最前面。当一个值使用时候,我们会重新储存过期时间,导致被经常使用的缓存,会存在字典的后面。而一但缓存的内容长度超过限制时候,这里会调用有序字典最前面的key(也即是近期相对用的最少的),并删除对应的内容,以达到lru的逻辑。

2、在将我们写好的算法改成装饰器:

  from functools import wraps  from my_cache import lrucachedict        def lru_cache(max_size=1024, expiration=60, types='lru'):      if types == 'lru' or types == 'lru':          my_cache = lrucachedict(max_size=max_size, expiration=expiration)         def wrapper(func):          @wraps(func)          def inner(*args, **kwargs):              key = repr(*args, **kwargs)              try:                  result = my_cache[key]              except keyerror:                  result = func(*args, **kwargs)                  my_cache[key] = result              return result             return inner         return wrapper  

这里需要解释的是直接使用 my_cache[key],这个类似字典的方法,实际上是调用了 lrucachedict 中的 __contations__方法,这也是字典中实现通过key取值的方法。这个装饰器里,我加入了types的参数,你们可以根据需求,实现不同的缓存算法,丰富这个装饰器的功能,而lru缓存本身,其实已经是python的标准库了,可以引入functools.lru_cache来调用。

到此这篇关于python 如何手动编写一个自己的lru缓存装饰器的方法实现的文章就介绍到这了,更多相关python lru缓存装饰器内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

需要了解更多python教程分享Python 如何手动编写一个自己的LRU缓存装饰器的方法实现,都可以关注python教程分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/pythontutorial/996515.html

(0)
上一篇 2021年12月28日
下一篇 2021年12月28日

精彩推荐