Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 54f185b

Browse files
authored
bpo-44782: Improve OrderedDict recipe for LRU cache variants (GH-27536)
1 parent 28b6dc9 commit 54f185b

1 file changed

Lines changed: 32 additions & 16 deletions

File tree

Doc/library/collections.rst

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,27 +1171,43 @@ original insertion position is changed and moved to the end::
11711171
self.move_to_end(key)
11721172

11731173
An :class:`OrderedDict` would also be useful for implementing
1174-
variants of :func:`functools.lru_cache`::
1174+
variants of :func:`functools.lru_cache`:
11751175

1176-
class LRU(OrderedDict):
1177-
'Limit size, evicting the least recently looked-up key when full'
1176+
.. testcode::
11781177

1179-
def __init__(self, maxsize=128, /, *args, **kwds):
1180-
self.maxsize = maxsize
1181-
super().__init__(*args, **kwds)
1178+
class LRU:
11821179

1183-
def __getitem__(self, key):
1184-
value = super().__getitem__(key)
1185-
self.move_to_end(key)
1180+
def __init__(self, func, maxsize=128):
1181+
self.func = func
1182+
self.maxsize = maxsize
1183+
self.cache = OrderedDict()
1184+
1185+
def __call__(self, *args):
1186+
if args in self.cache:
1187+
value = self.cache[args]
1188+
self.cache.move_to_end(args)
1189+
return value
1190+
value = self.func(*args)
1191+
if len(self.cache) >= self.maxsize:
1192+
self.cache.popitem(False)
1193+
self.cache[args] = value
11861194
return value
11871195
1188-
def __setitem__(self, key, value):
1189-
if key in self:
1190-
self.move_to_end(key)
1191-
super().__setitem__(key, value)
1192-
if len(self) > self.maxsize:
1193-
oldest = next(iter(self))
1194-
del self[oldest]
1196+
.. doctest::
1197+
:hide:
1198+
1199+
>>> def square(x):
1200+
... return x ** 2
1201+
...
1202+
>>> s = LRU(square, maxsize=5)
1203+
>>> actual = [(s(x), s(x)) for x in range(20)]
1204+
>>> expected = [(x**2, x**2) for x in range(20)]
1205+
>>> actual == expected
1206+
True
1207+
>>> actual = list(s.cache.items())
1208+
>>> expected = [((x,), x**2) for x in range(15, 20)]
1209+
>>> actual == expected
1210+
True
11951211

11961212

11971213
:class:`UserDict` objects

0 commit comments

Comments
 (0)