inversion_ideas.decorators.cache_on_model#

inversion_ideas.decorators.cache_on_model(func)#

Cache the last result of a method within the instance using the model hash.

Important

Use this decorator only for methods that take the model as the first argument.

Hint

If the instance has a cache bool attribute, useres can enable or disable caching within the decorated method. If cache=True, the result of the decorated method will be cached. If cache=False, no caching will be performed.

See also

functools.cache()

Use this other decorator for caching multiple results.

Examples

Let’s decorate a method that will return the cached result when called again with the same model argument:

>>> import numpy as np
>>>
>>> class MyClass:
...
...     @cache_on_model
...     def squared(self, model) -> float:
...         return (model ** 2).sum()
>>>
>>> sq = MyClass()

When calling the method with a given model we’ll perform the computation:

>>> model = np.array([1.0, 2.0, 3.0])
>>> print(sq.squared(model))  # perform the computation
14.0

Next time we call it with the same model, it’ll return the cached value:

>>> print(sq.squared(model))  # access the cached result
14.0

When calling the method with a different model, we’ll trigger a new computation. And the new result will be cached:

>>> model_new = np.array([4.0, 5.0, 6.0])
>>> print(sq.squared(model_new))  # perform a new computation
77.0

Important

Only the last value gets cached to be cautious about memory usage.

Users could control wether to cache or not through the cache attribute:

>>> class MyClass:
...
...     def __init__(self, cache):
...         self.cache = cache
...
...     @cache_on_model
...     def squared(self, model) -> float:
...         return (model ** 2).sum()

The following instance caches the result:

>>> sq_cache = MyClass(cache=True)
>>> model = np.array([1.0, 2.0, 3.0])
>>> sq_cache.squared(model)  # perform the computation
np.float64(14.0)
>>> sq_cache.squared(model)  # returns cached object
np.float64(14.0)

This one does not:

>>> sq_no_cache = MyClass(cache=False)
>>> model = np.array([1.0, 2.0, 3.0])
>>> sq_no_cache.squared(model)  # perform the computation
np.float64(14.0)
>>> sq_no_cache.squared(model)  # perform the computation
np.float64(14.0)