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:
The cachedmethod decorator would be as follow (The code is not tested):
Decorators make magic easy.
class myTool(...):
@cachedmethod
def getMyDataFromDB(*args, **kw):
data = fetch_mydata_from_db()
return data
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