annotate pyikriam/utils.py @ 315:97a838fcdd05

merged
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Mon, 05 Jan 2009 00:19:40 +0800
parents 7551342718b6
children
rev   line source
160
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
1 ## \brief decorator is a class decorate another of another object.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
2 #
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
3 # Access of attributes/methods that can not be found in an instance
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
4 # of a class of this meta-class, decorator, are delegated to the backend
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
5 # of the instance.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
6 #
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
7 # A backend object always passed as first parameter when
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
8 # instantiate an instance of a class with decorator as meta-class.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
9 # For example,
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
10 # \code
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
11 # class foo(object):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
12 # __metaclass__ = decorator
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
13 #
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
14 # backend.data = 3
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
15 # obj = foo(backend)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
16 # print obj.data
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
17 # backend.data = 4
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
18 # print obj.data
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
19 # \endcode
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
20 # it print out 3 and 4 respectively.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
21 #
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
22 class decorator(type):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
23 def __init__(clz, name, base, dict):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
24 super(decorator, clz).__init__(name, base, dict)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
25 clz.__getattr__ = decorator.__dele_getattr
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
26 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
27
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
28 @staticmethod
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
29 def set_backend(obj, backend):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
30 obj.__backend = backend
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
31 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
32
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
33 @staticmethod
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
34 def __dele_getattr(obj, name):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
35 return getattr(obj.__backend, name)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
36 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
37
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
38
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
39 ## \brief Decorator to make functions or methods dynamic programming.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
40 #
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
41 # dyna_prog result of functions or methods with their arguments as key.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
42 # It supposes result of a function always the same if the same arguments
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
43 # are passed. It cache result of cached function to avoid really calling
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
44 # function every time.
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
45 class dyna_prog(object):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
46 class functor(object):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
47 def __init__(self, instance, method):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
48 self._method = method
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
49 self._instance = instance
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
50 self._cache = {}
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
51 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
52
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
53 def __call__(self, *args):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
54 try:
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
55 return self._cache[args]
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
56 except KeyError:
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
57 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
58 instance = self._instance
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
59 result = self._method(instance, *args)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
60 return self._cache.setdefault(args, result)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
61
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
62 def clear(self):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
63 self._cache.clear()
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
64 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
65
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
66 def __init__(self, method):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
67 super(dyna_prog, self).__init__()
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
68 self._method = method
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
69 self._functors = {}
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
70 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
71
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
72 def __get__(self, instance, owner):
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
73 try:
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
74 return self._functors[instance]
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
75 except KeyError:
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
76 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
77 functor_o = dyna_prog.functor(instance, self._method)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
78 return self._functors.setdefault(instance, functor_o)
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
79 pass
7551342718b6 Refactory pyikriam with patterns.
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
80