I was generating some reports recently that involved accessing expensive object methods whose results were known to not change on subsequent calls; However, instead of using local variables, I sketched-out this quick memoization decorator to save method responses as variables on the object (using a leading '_' followed by the method-name as the variable name):
def cache_method_results(fn): def _view(self, *args, **kwargs): var_name = '_{n}'.format(n=fn.__name__) if var_name in self.__dict__: # Return the copy we have return self.__dict__[var_name] else: # Run the function and save its result self.__dict__[var_name] = fn(self, *args, **kwargs) return self.__dict__[var_name] return _view
You might use it like this:
class Foo(object): @cache_method_results def some_expensive_operation(self): ...calculate something big and unchanging... return results f = Foo() print(f.some_expensive_operation()) # This first call will run the calculation ... print(f.some_expensive_operation()) # but this one will used the cached result instead
It's not rocket science, but these little tricks add to the fun of using Python.