Repository URL to install this package:
Version:
2.4.1b2 ▾
|
import functools
from django.utils.functional import cached_property
# Need to inherit from object explicitly, to turn ``cached_classmethod`` in to
# a new-style class. WeakKeyDictionary is an old-style class, which do not
# support descriptors.
class cached_classmethod(dict):
"""
Cache the result of a no-arg class method.
.. code-block:: python
class Foo:
@cached_classmethod
def bar(cls):
# Some expensive computation
return 'baz'
Similar to ``@lru_cache``, but the cache is per-class, stores a single
value, and thus doesn't fill up; where as ``@lru_cache`` is global across
all classes, and could fill up if too many classes were used.
"""
def __init__(self, fn):
self.fn = fn
functools.update_wrapper(self, fn)
def __get__(self, instance, owner):
""" Get the class_cache for this type when accessed """
return self[owner]
def __missing__(self, cls):
""" Make a new class_cache on cache misses """
value = _cache(self, cls, self.fn)
self[cls] = value
return value
class _cache:
""" Calls the real class method behind when called, caching the result """
def __init__(self, cache, cls, fn):
self.cache = cache
self.cls = cls
self.fn = fn
functools.update_wrapper(self, fn)
@cached_property
def value(self):
""" Generate the cached value """
return self.fn(self.cls)
def __call__(self):
""" Get the cached value """
return self.value
def cache_clear(self):
""" Clear the cached value. """
# Named after lru_cache.cache_clear
self.cache.pop(self.cls, None)