简体   繁体   中英

Understanding this memoize decorator

I am having trouble understanding this memoize decorator

def method(func):
    """
    Decorator for caching parameterless bound method
    """
    key = '_memoize_%s' % func.__name__
    @wraps(func)
    def wrapper(self):
        if not hasattr(self, key):
            setattr(self, key, func(self))
        return getattr(self, key)

    return wrapper

Let's say I have:

@method
def add(x,y):
    return x+y

Is it attaching a key _memoize_add to the tuple (x,y), since that's what's being passed to the wrapper.

The decorator stores the return value of a method as a private attribute. So it will only work with a class instance, and not with an ordinary function.

The func argument of the decorator is the method it is wrapping, and the returned wrapper function will end up being called instead of the method. When the wrapper is called, its self argument will be the instance of the class, and so the settattr call will cache the result of func as a private attribute named by key . After that, all further calls will return the cached value of the key attribute instead.

Here's a simple test that shows how it could be used:

import random
from functools import wraps

def method(func):
    key = '_memoize_%s' % func.__name__
    @wraps(func)
    def wrapper(self):
        if not hasattr(self, key):
            setattr(self, key, func(self))
        return getattr(self, key)

    return wrapper

class Test(object):
    @method
    def cached(self):
        return random.random()

    def uncached(self):
        return random.random()

t = Test()
for x in range(3):
    print('cached: %s' % t.cached())
    print('uncached: %s' % t.uncached())
print(t.__dict__)

Output:

cached: 0.6594806157188309
uncached: 0.2492466307551897
cached: 0.6594806157188309
uncached: 0.08718572660830726
cached: 0.6594806157188309
uncached: 0.5501638352647334
{'_memoize_cached': 0.6594806157188309}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM