django_auxilium.utils.functools.cache module¶
-
class
django_auxilium.utils.functools.cache.
BaseCache
(parent, attr)[source]¶ Bases:
object
Base class for implementing cache implementations
Parameters: - parent (object) – A parent object where cache is stored
- attr (str) – Name of the attribute under which cache will be stored
in the
parent
object
-
delete
(*args, **kwargs)[source]¶ This method must be overwritten by subclasses which should delete cache value for the given parameters
args
andkwargs
are the parameters passed to the cached function and can be used by the method to determine which cache value from theparent
object to removeWhen cache value is not found, this method should raise
NotInCache
-
get
(*args, **kwargs)[source]¶ This method must be overwritten by subclasses which should return cache value
args
andkwargs
are the parameters passed to the cached function and can be used by the method to extract the cache value from theparent
objectWhen cache value is not found, this method should raise
NotInCache
-
class
django_auxilium.utils.functools.cache.
BaseCacheDecorator
(is_method=None)[source]¶ Bases:
django_auxilium.utils.functools.decorators.HybridDecorator
Base decorator for caching callables so that they only execute once and all subsequent calls return cached value
This is very useful for expensive functions
-
cache_class
¶ Caching implementation to use when wrapping standalone functions. This attribute is meant to be changed in subclasses.
alias of
Caching
-
cache_descriptor_class
= None¶ Descriptor class to be used when caching is applied to class methods. This attribute is meant to be changed in subclasses.
-
get_wrapped_object
()[source]¶ Main method for wrapping the given object.
This method has separate code paths for the following scenarios:
Class method: When wrapping class method descriptor is returned as created by get_cache_descriptor()
. That descriptor is then responsible for maintaining cache state for the class instance.Function: When wrapping standalone function, this method returns a wrapping function which caches the value on this decorator instance. That means that the cache becomes global since functions in Python are singletons.
-
-
class
django_auxilium.utils.functools.cache.
CacheDecorator
(as_property=False, *args, **kwargs)[source]¶ Bases:
django_auxilium.utils.functools.cache.BaseCacheDecorator
Decorator for caching callables so that they only execute once and all subsequent calls return cached value.
Note
This caching decorator does not account function parameters to cache values. If you need to cache different calls per given parameters, please look at
MemoizeDecorator
Examples
When caching standalone functions:
>>> @CacheDecorator.as_decorator() ... def compute(): ... print('computing here') ... return 'foo' >>> print(compute()) computing here foo >>> print(compute()) foo >>> print(compute.pop()) foo >>> print(compute()) computing here foo
When caching class methods:
>>> class Foo(object): ... @CacheDecorator.as_decorator() ... def foo(self): ... print('computing here') ... return 'foo' >>> f = Foo() >>> print(f.foo()) computing here foo >>> print(f.foo()) foo >>> print(f.foo.pop()) foo >>> print(f.foo()) computing here foo
Parameters: as_property (bool) – Boolean whether to create a property descriptor when using it on a class method
Warning
This is only meant to be used when the wrapping method does not accept any parameters since there is no way in Python to pass parameters to properties
-
cache_descriptor_class
¶ Descriptor class to be used when caching is applied to class methods
alias of
CacheDescriptor
-
-
class
django_auxilium.utils.functools.cache.
CacheDescriptor
(method, cache_class=None, as_property=False)[source]¶ Bases:
object
Cache descriptor to be used to add instance-level cache to class methods.
Note
This descriptor could be used independently (and there are even some examples below) however it is meant to be used along with
CacheDecorator
which provides much cleaner API.Examples
>>> def bar(self): ... print('computing') ... return 'bar' >>> class Foo(object): ... foo = CacheDescriptor(bar) >>> f = Foo() >>> print(f.foo()) computing bar >>> print(f.foo()) bar >>> print(f.foo.pop()) bar >>> print(f.foo()) computing bar >>> f.foo.push('another value') >>> print(f.foo()) another value
Parameters: - method (function) – Callable which this descriptor is meant to wrap and cache
- cache_class (type, optional) – Caching implementation cache which should be used to
apply caching. By default
default_cache_class
is used. - as_property (bool, optional) –
Whether to implement the descriptor as a property. By default it is
False
.Warning
This option as
True
can only be used with some caching implementations such asCaching
. Other implementations do not suppose this.
-
cache_attribute_pattern
= u'{name}_cache_{hash}'¶ String pattern for constructing the cache attribute name under which cache will be stored on the instance. This attribute is meant to be changed in subclasses to customize the functionality.
-
default_cache_class
¶ Cache implementation class which will be used for the caching. This attribute is meant to be changed in subclasses to customize the functionality.
alias of
Caching
-
get_cache
(instance)[source]¶ Helper method which given returns cache implementation instance for the given instance with given parameters
-
getter
(instance, *args, **kwargs)[source]¶ Wrapper method around the decorator-wrapped callable (
method
parameter) which returns cache value when available or otherwise computes and stores the value in cache by evaluating wrapped method
-
class
django_auxilium.utils.functools.cache.
Caching
(parent, attr)[source]¶ Bases:
django_auxilium.utils.functools.cache.BaseCache
Caching implementation which stores single cache value on the parent object
The cache is simply stored on the given attribute. When the attribute is present on the
parent
object, that indicates that the cache was set and that value is used for cache. When not present, that means cache is missing and henceNotInCache
is raised in most use-cases.-
delete
(*args, **kwargs)[source]¶ Delete the cache value from the
parent
objectRaises: NotInCache
– When the cache is not set and so cannot be deleted
-
get
(*args, **kwargs)[source]¶ Get the cache value from the
parent
objectRaises: NotInCache
– When the cache is not set
-
-
class
django_auxilium.utils.functools.cache.
MemoizeDecorator
(is_method=None)[source]¶ Bases:
django_auxilium.utils.functools.cache.BaseCacheDecorator
Decorator for memoizing functions so that they only execute once and all subsequent calls with same parameters
This is very useful for expensive functions which accept parameters
Examples
When caching standalone functions:
>>> @MemoizeDecorator.as_decorator() ... def compute(x): ... print('computing for', x) ... return x + 'foo' >>> print(compute('bar')) computing for bar barfoo >>> print(compute('awesome')) computing for awesome awesomefoo >>> print(compute('bar')) barfoo >>> print(compute.pop('bar')) barfoo >>> print(compute('bar')) computing for bar barfoo >>> print(compute('awesome')) awesomefoo
When caching class methods:
>>> class Foo(object): ... @MemoizeDecorator.as_decorator() ... def foo(self, x): ... print('computing for', x) ... return x + 'foo' >>> f = Foo() >>> print(f.foo('bar')) computing for bar barfoo >>> print(f.foo('awesome')) computing for awesome awesomefoo >>> print(f.foo('bar')) barfoo >>> print(f.foo('awesome')) awesomefoo >>> print(f.foo.pop('bar')) barfoo >>> print(f.foo('bar')) computing for bar barfoo >>> print(f.foo('awesome')) awesomefoo
-
cache_descriptor_class
¶ Descriptor class to be used when caching is applied to class methods
alias of
MemoizeDescriptor
-
-
class
django_auxilium.utils.functools.cache.
MemoizeDescriptor
(method, cache_class=None, as_property=False)[source]¶ Bases:
django_auxilium.utils.functools.cache.CacheDescriptor
Cache descriptor to be used to add instance-level cache to class methods which considers method parameters when caching values.
In other words, this descriptor caches method results per given parameters.
Note
This descriptor could be used independently (and there are even some examples below) however it is meant to be used along with
MemoizeDecorator
which provides much cleaner API.Examples
>>> def bar(self, x): ... print('computing for', x) ... return x + 'bar' >>> class Foo(object): ... foo = MemoizeDescriptor(bar) >>> f = Foo() >>> print(f.foo('foo')) computing for foo foobar >>> print(f.foo('awesome')) computing for awesome awesomebar >>> print(f.foo('foo')) foobar >>> print(f.foo.pop('foo')) foobar >>> print(f.foo('foo')) computing for foo foobar >>> print(f.foo('awesome')) awesomebar
-
cache_attribute_pattern
= u'{name}_memoize_{hash}'¶ String pattern for constructing the cache attribute name under which cache will be stored on the instance. This attribute is meant to be changed in subclasses to customize the functionality.
-
-
class
django_auxilium.utils.functools.cache.
Memoizing
(parent, attr)[source]¶ Bases:
django_auxilium.utils.functools.cache.BaseCache
Caching implementation which stores single cache value for a set of given parameters on the parent object hence is called memoization
The cache is stored on the given attribute as a dictionary. Keys are string representations of the given parameters to the cached function and the values are their corresponding cache values. When the key is in the dictionary, that is used as cache value. Otherwise, in most cases
NotInCache
is raised.-
delete
(*args, **kwargs)[source]¶ Delete the cache value from the
parent
object for the key as computed by the given parametersRaises: NotInCache
– When the cache is not set and so cannot be deleted
-
get
(*args, **kwargs)[source]¶ Get the cache value from the
parent
object by computing the key from the given parametersRaises: NotInCache
– When the cache is not set
-
-
exception
django_auxilium.utils.functools.cache.
NotInCache
[source]¶ Bases:
exceptions.Exception
Exception for when a value is not present in cache.
Primary purpose of the exception is to normalize various exception types from different cache implementations.
-
django_auxilium.utils.functools.cache.
cache
(*args, **kwargs)¶ Decorator for caching callables so that they only execute once and all subsequent calls return cached value.
Note
This caching decorator does not account function parameters to cache values. If you need to cache different calls per given parameters, please look at
MemoizeDecorator
Examples
When caching standalone functions:
>>> @CacheDecorator.as_decorator() ... def compute(): ... print('computing here') ... return 'foo' >>> print(compute()) computing here foo >>> print(compute()) foo >>> print(compute.pop()) foo >>> print(compute()) computing here foo
When caching class methods:
>>> class Foo(object): ... @CacheDecorator.as_decorator() ... def foo(self): ... print('computing here') ... return 'foo' >>> f = Foo() >>> print(f.foo()) computing here foo >>> print(f.foo()) foo >>> print(f.foo.pop()) foo >>> print(f.foo()) computing here foo
Parameters: as_property (bool) – Boolean whether to create a property descriptor when using it on a class method
Warning
This is only meant to be used when the wrapping method does not accept any parameters since there is no way in Python to pass parameters to properties
-
django_auxilium.utils.functools.cache.
cache_method
(*args, **kwargs)¶ Shortcut for
cache
which automatically indicates that the cached object is a method.These are equivalent:
class Foo(object): @cache(is_method=True) def foo(self): pass class Foo(object): @cache_method def bar(self): pass
-
django_auxilium.utils.functools.cache.
cache_property
(*args, **kwargs)¶ Shortcut for
cache
which automatically creates properties when used on class methods.These are equivalent:
@cache(as_property=True) def foo(self): pass @cache_property def bar(self): pass
-
django_auxilium.utils.functools.cache.
memoize
(*args, **kwargs)¶ Decorator for memoizing functions so that they only execute once and all subsequent calls with same parameters
This is very useful for expensive functions which accept parameters
Examples
When caching standalone functions:
>>> @MemoizeDecorator.as_decorator() ... def compute(x): ... print('computing for', x) ... return x + 'foo' >>> print(compute('bar')) computing for bar barfoo >>> print(compute('awesome')) computing for awesome awesomefoo >>> print(compute('bar')) barfoo >>> print(compute.pop('bar')) barfoo >>> print(compute('bar')) computing for bar barfoo >>> print(compute('awesome')) awesomefoo
When caching class methods:
>>> class Foo(object): ... @MemoizeDecorator.as_decorator() ... def foo(self, x): ... print('computing for', x) ... return x + 'foo' >>> f = Foo() >>> print(f.foo('bar')) computing for bar barfoo >>> print(f.foo('awesome')) computing for awesome awesomefoo >>> print(f.foo('bar')) barfoo >>> print(f.foo('awesome')) awesomefoo >>> print(f.foo.pop('bar')) barfoo >>> print(f.foo('bar')) computing for bar barfoo >>> print(f.foo('awesome')) awesomefoo