Below you can find an input based cache system implemented as a Python function decorator:
Edit 1: Edited the cache class, now it supports both arguments and keyword arguments, and I didn't delete the lines that has print commands, so you can uncomment the lines to see which one of the methods runs when
########################################################################
class InputBasedCachedMethod(object):
"""caches the result of a class method inside the instance based on the input
"""
#----------------------------------------------------------------------
def __init__(self, method):
# record the unbound-method and the name
#print "running __init__ in InputBasedCachedMethod"
self._method = method
self._name = method.__name__
self._obj = None
#----------------------------------------------------------------------
def __get__(self, inst, cls):
"""use __get__ just to get the instance object
"""
#print "running __get__ in InputBasedCachedMethod"
self._obj = inst
if not hasattr( self._obj, self._name + "._outputData" ):
#print "creating the data"
setattr ( self._obj, self._name + "._outputData", list() )
setattr ( self._obj, self._name + "._inputData", list() )
#print "finished creating data"
return self
#----------------------------------------------------------------------
def __call__(self, *args, **keys):
"""for now it uses only one argument
"""
#print "running __call__ in InputBasedCachedMethod"
outputData = getattr( self._obj, self._name + "._outputData" )
inputData = getattr( self._obj, self._name + "._inputData" )
# combine args and keys
argsKeysCombined = list()
argsKeysCombined.append( args )
argsKeysCombined.append( keys )
if (not argsKeysCombined in inputData) or outputData == None:
#print "calculating new data"
data = self._method(self._obj, *args, **keys)
inputData.append( argsKeysCombined )
outputData.append( data )
setattr( self._obj, self._name + "._inputdata", inputData )
setattr( self._obj, self._name + "._outputData", outputData )
return data
else:
#print "returning cached data"
return outputData[ inputData.index( argsKeysCombined ) ]
#----------------------------------------------------------------------
def __repr__(self):
"""Return the function's repr
"""
#print "running __repr_ in InputBasedCachedMethod"
objectsRepr = str(self._obj)
objectsName = objectsRepr.split(' ')[0].split('.')[-1]
cachedObjectsRepr = ''
return cachedObjectsRepr
Edit 1: Edited the cache class, now it supports both arguments and keyword arguments, and I didn't delete the lines that has print commands, so you can uncomment the lines to see which one of the methods runs when
Comments