view pyikriam/utils.py @ 170:7df753a99926

merged
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Sun, 02 Nov 2008 02:23:13 +0800
parents 7551342718b6
children
line wrap: on
line source

## \brief decorator is a class decorate another of another object.
#
# Access of attributes/methods that can not be found in an instance
# of a class of this meta-class, decorator, are delegated to the backend
# of the instance.
#
# A backend object always passed as first parameter when
# instantiate an instance of a class with decorator as meta-class.
# For example,
# \code
# class foo(object):
#     __metaclass__ = decorator
#
# backend.data = 3
# obj = foo(backend)
# print obj.data
# backend.data = 4
# print obj.data
# \endcode
# it print out 3 and 4 respectively.
# 
class decorator(type):
    def __init__(clz, name, base, dict):
        super(decorator, clz).__init__(name, base, dict)
        clz.__getattr__ = decorator.__dele_getattr
        pass

    @staticmethod
    def set_backend(obj, backend):
        obj.__backend = backend
        pass

    @staticmethod
    def __dele_getattr(obj, name):
        return getattr(obj.__backend, name)
    pass


## \brief Decorator to make functions or methods dynamic programming.
#
# dyna_prog result of functions or methods with their arguments as key.
# It supposes result of a function always the same if the same arguments
# are passed.  It cache result of cached function to avoid really calling
# function every time.
class dyna_prog(object):
    class functor(object):
        def __init__(self, instance, method):
            self._method = method
            self._instance = instance
            self._cache = {}
            pass

        def __call__(self, *args):
            try:
                return self._cache[args]
            except KeyError:
                pass
            instance = self._instance
            result = self._method(instance, *args)
            return self._cache.setdefault(args, result)

        def clear(self):
            self._cache.clear()
        pass

    def __init__(self, method):
        super(dyna_prog, self).__init__()
        self._method = method
        self._functors = {}
        pass
    
    def __get__(self, instance, owner):
        try:
            return self._functors[instance]
        except KeyError:
            pass
        functor_o = dyna_prog.functor(instance, self._method)
        return self._functors.setdefault(instance, functor_o)
    pass