Python LRU Cache Decorator Per Instance

前端 未结 3 1449
情书的邮戳
情书的邮戳 2020-12-13 09:16

Using the LRU Cache decorator found here: http://code.activestate.com/recipes/578078-py26-and-py30-backport-of-python-33s-lru-cache/

from lru_cache import lr         


        
相关标签:
3条回答
  • 2020-12-13 09:25

    Assuming you don't want to modify the code (e.g., because you want to be able to just port to 3.3 and use the stdlib functools.lru_cache, or use functools32 out of PyPI instead of copying and pasting a recipe into your code), there's one obvious solution: Create a new decorated instance method with each instance.

    class Test:
        def cached_method(self, x):
             return x + 5
        def __init__(self):
             self.cached_method = lru_cache(maxsize=16)(self.cached_method)
    
    0 讨论(0)
  • 2020-12-13 09:29

    How about this: a function decorator that wraps the method with lru_cache the first time it's called on each instance?

    def instance_method_lru_cache(*cache_args, **cache_kwargs):
        def cache_decorator(func):
            @wraps(func)
            def cache_factory(self, *args, **kwargs):
                print('creating cache')
                instance_cache = lru_cache(*cache_args, **cache_kwargs)(func)
                instance_cache = instance_cache.__get__(self, self.__class__)
                setattr(self, func.__name__, instance_cache)
                return instance_cache(*args, **kwargs)
            return cache_factory
        return cache_decorator
    

    Use it like this:

    class Foo:
        @instance_method_lru_cache()
        def times_2(self, bar):
            return bar * 2
    
    foo1 = Foo()
    foo2 = Foo()
    
    print(foo1.times_2(2))
    # creating cache
    # 4
    foo1.times_2(2)
    # 4
    
    print(foo2.times_2(2))
    # creating cache
    # 4
    foo2.times_2(2)
    # 4
    

    Here's a gist on GitHub with some inline documentation.

    0 讨论(0)
  • 2020-12-13 09:34

    These days, methodtools will work

    from methodtools import lru_cache
    class Test:
        @lru_cache(maxsize=16)
        def cached_method(self, x):
             return x + 5
    

    You need to install methodtools

    pip install methodtools
    

    If you are still using py2, then functools32 also is required

    pip install functools32
    
    0 讨论(0)
提交回复
热议问题