from jaraco functools 3 3 wrap lrucache to support storing the cache data in the object instances abstracts the common paradigm where the method explicitly saves an underscoreprefixed protected property on first call and returns that subsequently class myclass calls 0 methodcache def methodself value self calls 1 return value a myclass a method3 3 for x in range75 res a methodx a calls 75 note that the apparent behavior will be exactly like that of lrucache except that the cache is stored on each instance so values in one instance will not flush values from another and when an instance is deleted so are the cached values for that instance b myclass for x in range35 res b methodx b calls 35 a method0 0 a calls 75 note that if method had been decorated with functools lrucache a calls would have been 76 due to the cached value of 0 having been flushed by the b instance clear the cache with cacheclear a method cacheclear same for a method that hasn t yet been called c myclass c method cacheclear another cache wrapper may be supplied cache functools lrucachemaxsize2 myclass method2 methodcachelambda self 3 cachewrappercache a myclass a method2 3 caution do not subsequently wrap the method with another decorator such as property which changes the semantics of the function see also http code activestate comrecipes577452amemoizedecoratorforinstancemethods for another implementation and additional justification it s the first call replace the method with a cached bound method support cache clear even before cache has been created from jaraco functools 3 3 wrap func so it s not called if its first param is none printtext passnoneprint printtext text text printtextnone from jaraco functools 3 3 wrap lru_cache to support storing the cache data in the object instances abstracts the common paradigm where the method explicitly saves an underscore prefixed protected property on first call and returns that subsequently class myclass calls 0 method_cache def method self value self calls 1 return value a myclass a method 3 3 for x in range 75 res a method x a calls 75 note that the apparent behavior will be exactly like that of lru_cache except that the cache is stored on each instance so values in one instance will not flush values from another and when an instance is deleted so are the cached values for that instance b myclass for x in range 35 res b method x b calls 35 a method 0 0 a calls 75 note that if method had been decorated with functools lru_cache a calls would have been 76 due to the cached value of 0 having been flushed by the b instance clear the cache with cache_clear a method cache_clear same for a method that hasn t yet been called c myclass c method cache_clear another cache wrapper may be supplied cache functools lru_cache maxsize 2 myclass method2 method_cache lambda self 3 cache_wrapper cache a myclass a method2 3 caution do not subsequently wrap the method with another decorator such as property which changes the semantics of the function see also http code activestate com recipes 577452 a memoize decorator for instance methods for another implementation and additional justification it s the first call replace the method with a cached bound method support cache clear even before cache has been created from jaraco functools 3 3 wrap func so it s not called if its first param is none print_text pass_none print print_text text text print_text none
import types
import functools



def method_cache(method, cache_wrapper=None):
    
    cache_wrapper = cache_wrapper or functools.lru_cache()

    def wrapper(self, *args, **kwargs):
        
        bound_method = types.MethodType(method, self)
        cached_method = cache_wrapper(bound_method)
        setattr(self, method.__name__, cached_method)
        return cached_method(*args, **kwargs)

    
    wrapper.cache_clear = lambda: None

    return wrapper



def pass_none(func):
    

    @functools.wraps(func)
    def wrapper(param, *args, **kwargs):
        if param is not None:
            return func(param, *args, **kwargs)

    return wrapper