Я попытаюсь ответить на ваш запрос с примером того, как использовать модуль weakref
для реализации кэширования.Мы сохраним слабые ссылки нашего кэша в weakref.WeakValueDictionary
, а строгие ссылки - в collections.deque
, потому что он имеет свойство maxlen
, которое контролирует, сколько объектов он содержит.Реализовано в стиле закрытия функции:
import weakref, collections
def createLRUCache(factory, maxlen=64):
weak = weakref.WeakValueDictionary()
strong = collections.deque(maxlen=maxlen)
notFound = object()
def fetch(key):
value = weak.get(key, notFound)
if value is notFound:
weak[key] = value = factory(key)
strong.append(value)
return value
return fetch
Объект deque
сохранит только последние записи maxlen
, просто отбрасывая ссылки на старые записи, как только он достигнет емкости.Когда старые записи удаляются и мусор собирается Python, WeakValueDictionary
удалит эти ключи с карты.Следовательно, комбинация двух объектов помогает нам хранить только maxlen
записей в нашем LRU-кэше.
class Silly(object):
def __init__(self, v):
self.v = v
def fib(i):
if i > 1:
return Silly(_fibCache(i-1).v + _fibCache(i-2).v)
elif i: return Silly(1)
else: return Silly(0)
_fibCache = createLRUCache(fib)