mirror of
https://github.com/python/cpython.git
synced 2025-10-03 13:45:29 +00:00
bpo-44782: Improve OrderedDict recipe for LRU cache variants (GH-27536) (GH-27567)
This commit is contained in:
parent
e0d599fa48
commit
c50a672eeb
1 changed files with 31 additions and 15 deletions
|
@ -1149,27 +1149,43 @@ original insertion position is changed and moved to the end::
|
||||||
self.move_to_end(key)
|
self.move_to_end(key)
|
||||||
|
|
||||||
An :class:`OrderedDict` would also be useful for implementing
|
An :class:`OrderedDict` would also be useful for implementing
|
||||||
variants of :func:`functools.lru_cache`::
|
variants of :func:`functools.lru_cache`:
|
||||||
|
|
||||||
class LRU(OrderedDict):
|
.. testcode::
|
||||||
'Limit size, evicting the least recently looked-up key when full'
|
|
||||||
|
|
||||||
def __init__(self, maxsize=128, /, *args, **kwds):
|
class LRU:
|
||||||
|
|
||||||
|
def __init__(self, func, maxsize=128):
|
||||||
|
self.func = func
|
||||||
self.maxsize = maxsize
|
self.maxsize = maxsize
|
||||||
super().__init__(*args, **kwds)
|
self.cache = OrderedDict()
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __call__(self, *args):
|
||||||
value = super().__getitem__(key)
|
if args in self.cache:
|
||||||
self.move_to_end(key)
|
value = self.cache[args]
|
||||||
|
self.cache.move_to_end(args)
|
||||||
|
return value
|
||||||
|
value = self.func(*args)
|
||||||
|
if len(self.cache) >= self.maxsize:
|
||||||
|
self.cache.popitem(False)
|
||||||
|
self.cache[args] = value
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
.. doctest::
|
||||||
if key in self:
|
:hide:
|
||||||
self.move_to_end(key)
|
|
||||||
super().__setitem__(key, value)
|
>>> def square(x):
|
||||||
if len(self) > self.maxsize:
|
... return x ** 2
|
||||||
oldest = next(iter(self))
|
...
|
||||||
del self[oldest]
|
>>> s = LRU(square, maxsize=5)
|
||||||
|
>>> actual = [(s(x), s(x)) for x in range(20)]
|
||||||
|
>>> expected = [(x**2, x**2) for x in range(20)]
|
||||||
|
>>> actual == expected
|
||||||
|
True
|
||||||
|
>>> actual = list(s.cache.items())
|
||||||
|
>>> expected = [((x,), x**2) for x in range(15, 20)]
|
||||||
|
>>> actual == expected
|
||||||
|
True
|
||||||
|
|
||||||
|
|
||||||
:class:`UserDict` objects
|
:class:`UserDict` objects
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue