📅  最后修改于: 2023-12-03 15:23:26.956000             🧑  作者: Mango
LRU 缓存是一种常见的缓存策略,当缓存满时,会删除最近最少使用的缓存项。在Python中,我们可以利用lru_cache
装饰器实现LRU缓存。
lru_cache
可以用于缓存函数的返回值。例如,我们有一个函数fibonacci
,它返回斐波那契数列的前n项。
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print([fibonacci(n) for n in range(16)])
上述代码中,我们使用lru_cache
装饰了fibonacci
函数,并设置了最大缓存容量为128。调用fibonacci
函数时,如果参数n已经存在缓存中,函数将直接返回缓存中的值,否则将计算并缓存新的返回值。输出结果为:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
我们可以通过自定义缓存规则来实现更灵活的LRU缓存。例如,我们有一个数据结构LRUCache
,它具有以下方法:
get(key)
:获取键为key的值。如果key不存在,返回-1。put(key, value)
:设置键为key的值为value。如果缓存已满,删除最近最少使用的缓存项。如果key已经存在,更新对应的value值。我们可以定义一个装饰器函数lru_cache_custom
,接收最大缓存容量作为参数,返回一个装饰器。装饰器用于装饰类方法,并在装饰过程中注入LRU缓存逻辑。具体实现如下:
from functools import lru_cache, wraps
def lru_cache_custom(maxsize=128):
def decorator(func):
@wraps(func)
def wrapper(obj, key, *args, **kwargs):
if key in obj.cache:
obj.cache.move_to_end(key)
return obj.cache[key]
result = func(obj, key, *args, **kwargs)
obj.cache[key] = result
if len(obj.cache) > maxsize:
obj.cache.popitem(last=False)
return result
return wrapper
return decorator
上述装饰器函数中,我们定义了一个decorator
,它接收类方法func
作为参数,并返回一个装饰器函数wrapper
。wrapper
函数接收self
对象、key
值和其他参数,并根据LRU缓存策略进行缓存。如果key
存在于缓存中,我们将缓存项移动到字典的末尾,并返回缓存值。否则,我们调用原始函数计算结果,将结果缓存到字典中,并删除最近最少使用的缓存项。
注意,我们需要在decorator
函数和wrapper
函数上使用functools
模块中的wraps
装饰器,以保持被装饰的函数的元数据,如函数名、文档字符串等。
使用上述自定义装饰器,我们可以很容易地实现LRU缓存功能。例如,对于LRUCache
类,我们可以这样使用:
class LRUCache:
def __init__(self, capacity: int):
self.cache = OrderedDict()
self.capacity = capacity
@lru_cache_custom(maxsize=128)
def get(self, key: int) -> int:
return self.cache.get(key, -1)
@lru_cache_custom(maxsize=128)
def put(self, key: int, value: int) -> None:
self.cache[key] = value
if len(self.cache) > self.capacity:
self.cache.popitem(last=False)
在get
和put
方法上应用了自定义装饰器lru_cache_custom
,并注入了LRU缓存逻辑。cache
属性为有序字典,用于维护LRU缓存顺序。当调用get
方法时,如果key
存在于缓存中,我们将缓存项移动到字典的末尾,并返回缓存值;否则返回-1。当调用put
方法时,我们将键值对存储到字典中,并删除最近最少使用的缓存项,以保持缓存容量不超过capacity
。
LRU缓存是一种常见的缓存策略,在Python中可以使用lru_cache
装饰器实现。如果需要自定义缓存规则,可以编写一个装饰器函数,并将其应用于需要缓存的函数或类方法中。LRU缓存可以提高应用程序的性能,减少资源的浪费,是值得学习和掌握的技术。