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