理解这个memoize装饰器

时间:2014-11-11 20:54:48

标签: python

我无法理解这个memoize装饰器

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

让我说我有:

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

是否将一个键_memoize_add附加到元组(x,y),因为这是传递给包装器的内容。

1 个答案:

答案 0 :(得分:1)

装饰器将方法的返回值存储为私有属性。所以它只适用于类实例,而不适用于普通函数。

装饰器的func参数是它包装的方法,返回的wrapper函数最终将被调用而不是方法。调用包装器时,其self参数将是类的实例,因此settattr调用将func的结果缓存为key命名的私有属性}。之后,所有进一步的调用都将返回key属性的缓存值。

这是一个简单的测试,展示了如何使用它:

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__)

输出:

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