Python 如何手动编写一个自己的LRU缓存装饰器的方法实现
LRU缓存算法,指的是近期最少使用算法,大体逻辑就是淘汰最长时间没有用的那个缓存,这里我们使用有序字典,来实现自己的LRU缓存算法,并将其包装成一个装饰器。
1、首先创建一个my_cache.py文件 编写自己我们自己的LRU缓存算法,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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、在将我们写好的算法改成装饰器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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缓存装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
pyTorch深入学习梯度和Linear Regression实现
这篇文章主要介绍了pyTorch深入学习,实现梯度和Linear Regression,文中呈现了详细的示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助2021-09-09Python Django给admin添加Action的方法实例详解
这篇文章主要介绍了Django给admin添加Action的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-04-04
最新评论