Inspired by this caching recipe and to continue with the previous post, I think it will be more readable, clean and reusable if we use a decorator to cache methods inside a tool:

class myTool(...):

@cachedmethod
def getMyDataFromDB(*args, **kw):

data = fetch_mydata_from_db()

return data
Decorators make magic easy.

The cachedmethod decorator would be as follow (The code is not tested):


import types

def cachedmethod(function):
return types.MethodType(CacheMethod(function), None)


class CacheMethod:

def __init__(self,function):
if function.__class__.__name__ == 'instancemethod':
self._function = function
self._class = function.im_class
else:
raise TypeError('method expected')

if not hasattr(self._class,'ZCacheable_get'):
raise TypeError('class must inherit from OFS.Cache.Cacheable')

def __call__(self, *args, **kwds):
view_name = "class_%s_method_%s" % (id(self._class),
id(self._function))
cached_data = self._class.ZCacheable_get(view_name = view_name,
default = None)

if cached_data is None:
# no data in the cache, so cache it
cached_data = self._function(*args, **kwds)
self._class.ZCacheable_set(cached_data,
view_name=view_name)

return cached_data