Python怎样手动编写一个自己的LRU缓存装饰器
发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,Python怎样手动编写一个自己的LRU缓存装饰器,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。LRU缓存算法,指的是近期最少使用算法,
千家信息网最后更新 2025年01月20日Python怎样手动编写一个自己的LRU缓存装饰器
Python怎样手动编写一个自己的LRU缓存装饰器,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
LRU缓存算法,指的是近期最少使用算法,大体逻辑就是淘汰最长时间没有用的那个缓存,这里我们使用有序字典,来实现自己的LRU缓存算法,并将其包装成一个装饰器。
1、首先创建一个my_cache.py文件 编写自己我们自己的LRU缓存算法,代码如下:
import timefrom 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 wrapsfrom 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缓存装饰器的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!
缓存
字典
时间
算法
方法
有序
内容
逻辑
手动
代码
时候
更多
长度
问题
不同
最长
束手无策
为此
位置
功能
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
财政局网络安全知识测试
上海管理软件开发商
编码数据库
美国国家网络安全教育计划
植物数据库中科院
mysql数据库主主搭建
S扫描软件开发
华为ocx软件开发部
台风山竹的大数据库
轨道交通软件开发研究生
南山网络安全检查
杭州软件开发合法吗
谷歌邮箱服务器设置
适合做软件开发测试的笔记本
登课网互联网科技
融资租赁软件开发代码
网络安全监督管理内容
什么是数据库系统概念
电脑服务器增加带宽
网络安全检查都查什么
数据库代码日期怎么表示
深圳前端软件开发哪家专业
大型游戏软件开发
评论网络安全审查
通达oa 数据库root密码
新兴网络安全默安科技
色盲可以学软件开发吗
I根镜像服务器 断开互联网
获取服务器的环境变量
网吧怎么玩澳洲服务器