fsl.utils.memoize
This module provides a handful of decorators which may be used to memoize a function:
Memoize the given function by the value of the input arguments.
Decorator which can be used to memoize a function or method. Use like so::.
This class is intended to be used to decorate other decorators, so they can be applied to instance methods. For example, say we have the following class::.
Memoize the given function.
This decorator is intended for use with setter functions - a function which accepts a name and a value, and is intended to set some named attribute to the given value.
- fsl.utils.memoize.memoize(func=None)[source]
Memoize the given function by the value of the input arguments.
This function simply returns a
Memoize
instance.
- class fsl.utils.memoize.Memoize(*args, **kwargs)[source]
Bases:
object
Decorator which can be used to memoize a function or method. Use like so:
@memoize def myfunc(*a, **kwa): ... @memoize() def otherfunc(*a, **kwax): ...
A
Memoize
instance maintains a cache which contains{args : value}
mappings, whereargs
are the input arguments to the function, andvalue
is the value that the function returned for those arguments. When a memoized function is called with arguments that are present in the cache, the cached values are returned, and the function itself is not called.The
invalidate()
method may be used to clear the internal cache.Note that the arguments used for memoization must be hashable, as they are used as keys in a dictionary.
- invalidate(*args, **kwargs)[source]
Clears the internal cache. If no arguments are given, the entire cache is cleared. Otherwise, only the cached value for the provided arguments is cleared.
- __setFunction(*args, **kwargs)
Used internally to set the memoized function.
- __makeKey(*a, **kwa)
Constructs a key for use with the cache from the given arguments.
- __call__(*a, **kwa)[source]
Checks the cache against the given arguments. If a cached value is present, it is returned. Otherwise the memoized function is called, and its value is cached and returned.
- __dict__ = mappingproxy({'__module__': 'fsl.utils.memoize', '__doc__': 'Decorator which can be used to memoize a function or method. Use like\n so::\n\n @memoize\n def myfunc(*a, **kwa):\n ...\n\n @memoize()\n def otherfunc(*a, **kwax):\n ...\n\n A ``Memoize`` instance maintains a cache which contains ``{args : value}``\n mappings, where ``args`` are the input arguments to the function, and\n ``value`` is the value that the function returned for those arguments.\n When a memoized function is called with arguments that are present in the\n cache, the cached values are returned, and the function itself is not\n called.\n\n\n The :meth:`invalidate` method may be used to clear the internal cache.\n\n\n Note that the arguments used for memoization must be hashable, as they are\n used as keys in a dictionary.\n ', '__init__': <function Memoize.__init__>, 'invalidate': <function Memoize.invalidate>, '_Memoize__setFunction': <function Memoize.__setFunction>, '_Memoize__makeKey': <function Memoize.__makeKey>, '__call__': <function Memoize.__call__>, '__dict__': <attribute '__dict__' of 'Memoize' objects>, '__weakref__': <attribute '__weakref__' of 'Memoize' objects>, '__annotations__': {}})
- __module__ = 'fsl.utils.memoize'
- __weakref__
list of weak references to the object (if defined)
- fsl.utils.memoize.memoizeMD5(func)[source]
Memoize the given function. Whenever the function is called, an md5 digest of its arguments is calculated - if the digest has been previously cached, the previous value calculated by the function is returned.
- fsl.utils.memoize.skipUnchanged(func)[source]
This decorator is intended for use with setter functions - a function which accepts a name and a value, and is intended to set some named attribute to the given value.
This decorator keeps a cache of name-value pairs. When the decorator is called with a specific name and value, the cache is checked and, if the given value is the same as the cached value, the decorated function is not called. If the given value is different from the cached value (or there is no value), the decorated function is called.
The
invalidate
method may be called on askipUnchanged
-decorated function to clear the internal cache. For example:@skipUnchanged def setval(name, value): # ... # ... setval.invalidate()
Note
This decorator ignores the return value of the decorated function.
- Returns:
True
if the underlying setter function was called,False
otherwise.
- class fsl.utils.memoize.Instanceify(realDecorator)[source]
Bases:
object
This class is intended to be used to decorate other decorators, so they can be applied to instance methods. For example, say we have the following class:
class Container(object): def __init__(self): self.__items = {} @skipUnchanged def set(self, name, value): self.__items[name] = value
Given this definition, a single
skipUnchanged()
decorator will be created and shared amongst allContainer
instances. This is not ideal, as the value cache created by theskipUnchanged()
decorator should be associated with a singleContainer
instance.By redefining the
Container
class definition like so:class Container(object): def __init__(self): self.__items = {} @Instanceify(skipUnchanged) def set(self, name, value): self.__items[name] = value
a separate
skipUnchanged()
decorator is created for, and associated with, everyContainer
instance.This is achieved because an
Instanceify
instance is a descriptor. When first accessed as an instance attribute, anInstanceify
instance will create the real decorator function, and replace itself on the instance.- __init__(realDecorator)[source]
Create an
Instanceify
decorator.- Parameters:
realDecorator – A reference to the decorator that is to be instance-ified.
- __call__(func)[source]
Called immediately after
__init__()
, and passed the method that is to be decorated.
- __get__(instance, cls)[source]
When an
Instanceify
instance is accessed as an attribute of another object, it will create the real (instance-ified) decorator, and replace itself on the instance with the real decorator.
- __dict__ = mappingproxy({'__module__': 'fsl.utils.memoize', '__doc__': 'This class is intended to be used to decorate other decorators, so they\n can be applied to instance methods. For example, say we have the following\n class::\n\n class Container(object):\n\n def __init__(self):\n self.__items = {}\n\n @skipUnchanged\n def set(self, name, value):\n self.__items[name] = value\n\n\n Given this definition, a single :func:`skipUnchanged` decorator will be\n created and shared amongst all ``Container`` instances. This is not ideal,\n as the value cache created by the :func:`skipUnchanged` decorator should\n be associated with a single ``Container`` instance.\n\n\n By redefining the ``Container`` class definition like so::\n\n\n class Container(object):\n\n def __init__(self):\n self.__items = {}\n\n @Instanceify(skipUnchanged)\n def set(self, name, value):\n self.__items[name] = value\n\n\n a separate :func:`skipUnchanged` decorator is created for, and associated\n with, every ``Container`` instance.\n\n\n This is achieved because an ``Instanceify`` instance is a descriptor. When\n first accessed as an instance attribute, an ``Instanceify`` instance will\n create the real decorator function, and replace itself on the instance.\n ', '__init__': <function Instanceify.__init__>, '__call__': <function Instanceify.__call__>, '__get__': <function Instanceify.__get__>, '__dict__': <attribute '__dict__' of 'Instanceify' objects>, '__weakref__': <attribute '__weakref__' of 'Instanceify' objects>, '__annotations__': {}})
- __module__ = 'fsl.utils.memoize'
- __weakref__
list of weak references to the object (if defined)