fsl.utils.memoize

This module provides a handful of decorators which may be used to memoize a function:

memoize

Memoize the given function by the value of the input arguments.

Memoize

Decorator which can be used to memoize a function or method. Use like so::.

Instanceify

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::.

memoizeMD5

Memoize the given function.

skipUnchanged

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, where args are the input arguments to the function, and value 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.

__init__(*args, **kwargs)[source]

Create a Memoize object.

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 a skipUnchanged-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 all Container instances. This is not ideal, as the value cache created by the skipUnchanged() decorator should be associated with a single Container 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, every Container instance.

This is achieved because an Instanceify instance is a descriptor. When first accessed as an instance attribute, an Instanceify 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)