Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中使用@functools.LRU_decorator实现LRU缓存_Python_Functools_Lru - Fatal编程技术网

在python中使用@functools.LRU_decorator实现LRU缓存

在python中使用@functools.LRU_decorator实现LRU缓存,python,functools,lru,Python,Functools,Lru,所以我一直在尝试为我的项目实现一个LRU缓存, 使用python functools lru_缓存。 作为我的参考。 以下是参考中使用的代码 def timed_lru_cache(maxsize, seconds): def wrapper_cache(func): func = lru_cache(maxsize=maxsize)(func) func.lifetime = timedelta(seconds=seconds) func

所以我一直在尝试为我的项目实现一个LRU缓存, 使用python functools lru_缓存。 作为我的参考。 以下是参考中使用的代码

def timed_lru_cache(maxsize, seconds):
    def wrapper_cache(func):
        func = lru_cache(maxsize=maxsize)(func)
        func.lifetime = timedelta(seconds=seconds)
        func.expiration = datetime.utcnow() + func.lifetime

        @wraps(func)
        def wrapped_func(*args, **kwargs):
            if datetime.utcnow() >= func.expiration:
                func.cache_clear()
                func.expiration = datetime.utcnow() + func.lifetime

            return func(*args, **kwargs)

        return wrapped_func

    return wrapper_cache

    @timed_lru_cache(maxsize=config.cache_size, seconds=config.ttl)
    def load_into_cache(id):
        return object
在已包装的func部分中,
func.cache\u clear()
清除整个缓存以及所有项。 插入后,我需要帮助仅删除过期的元素。
有什么解决办法吗?

我认为调整现有的
lru\u缓存并不容易,而且我认为链接方法也不是很清楚

相反,我从头开始实现了一个定时lru缓存。有关用法,请参见顶部的docstring

它基于输入的
args
kwargs
存储密钥,并管理两种结构:

  • key=>(到期,结果)的映射
  • 最近使用的列表,其中第一项是最近使用最少的
每次尝试获取项目时,都会在“最近使用”列表中查找该键。如果不存在,则会将其添加到列表和映射中。如果有,我们检查是否过期。如果是,我们将重新计算结果,并进行更新。否则,我们可以返回映射中的任何内容

从datetime导入datetime,timedelta
从functools导入包装
输入import Any、Dict、List、Optional、Tuple
类TimedRuCache:
“”“缓存,它根据到期时间和最近使用的最少时间缓存结果。”。
如果项目过期,则首先删除这些项目,如果正在删除的“最近”项目太多,则删除这些项目
存储。
有两种方法可以使用此缓存,一种是“get”方法,另一种是将其作为缓存调用
decorator.get方法接受任何任意函数,但参数是
在键中考虑,因此建议不要混合功能。
>>>缓存=时间缓存(5)
>>>def foo(一):
…返回i+1
>>>cache.get(foo,1)#运行foo
>>>cache.get(foo,1)#返回先前计算的结果
作为一名装饰师,我们更熟悉:
>>>@TimedLRUCache(5)
…def foo(i):
…返回i+1
>>>富(1)#经营富
>>>foo(1)#返回先前计算的结果
任何一种方法都可以允许对缓存进行细粒度控制:
>>>五秒缓存=时间缓存(5)
>>>@5秒缓存
…def foo(i):
…返回i+1
>>>五秒缓存。清除缓存()#重置缓存(清除所有项)
>>>五秒缓存。prune()#清除无效项
"""
_条目:Dict[int,Tuple[datetime,Any]]
_最近添加:列表[int]
delta:timedelta
最大尺寸:int
def uu init uuu(self,秒:可选[int]=None,最大大小:可选[int]=None):
self.delta=timedelta(秒=秒),如果秒,则为无
self.max\u size=max\u size
self.\u items={}
self.\u最近添加的=[]
定义调用(self,func):
@包装(func)
def包装(*args,**kwargs):
返回self.get(func、args、kwargs)
返回包装器
@静力学方法
def_get_key(args,kwargs)->int:
“”“获取我们将用于查找缓存中项目的内容。”“”
key=(参数,元组(已排序(kwargs.items()))
返回散列(键)
def_更新(self,key:int,item:Any)->无:
“”“确保项目是最新的。”“”
如果键入self.\u最近添加:
self.\u最近添加。删除(键)
#列表中的第一项是最近使用最少的
self.\u最近添加。追加(键)
self._items[key]=(datetime.now()+self.delta,item)
#调用此函数时,某些内容发生了更改,因此我们还可以对缓存进行排序
self.prune()
def prune(自我):
“”“清除缓存中不再属于的所有内容
首先删除所有已过期的内容,然后删除所有非最近的内容(仅限
如果有“最大尺寸”)。
"""
#清除缓存中不再属于的任何内容。
当前时间=datetime.now()
#先把过期的东西扔掉
对于self.\u items.items()中的键,(到期,项):
如果到期时间<当前时间:
删除自身项目[关键]
self.\u最近添加。删除(键)
#然后确保最近没有太多的项目
如果self.max_大小:
self.\u最近添加了[:-self.max\u size]=[]
def清除缓存(自):
“”“清除缓存中的所有内容”“”
self.\u items={}
self.\u最近添加的=[]
def get(self、func、args、kwargs):
“”“给定函数及其参数,使用缓存获取结果
从函数的参数中获取密钥。如果密钥在缓存中,则
该密钥的过期时间尚未过去,请从缓存返回结果。
如果密钥*已*过期,或者“最近”项太多,请重新计算结果,
将其添加到缓存中,然后返回结果。
"""
key=self.\u get\u key(args,kwargs)
当前时间=datetime.now()
如果键入self.\u最近添加:
#缓存里有东西
到期日,item=self.\u items.get(键)
如果到期时间<当前时间:
#该项已过期,因此我们需要获取新值
新项目=函数(*args,**kwargs)
自我更新(密钥、新项目)
返回新项目
其他:
#我们可以使用现有的值
退货项目
其他:
#以前从未见过这个,所以添加它
新项目=函数(*args,**kwargs)
自我更新(键,n