Reputation: 8088
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.
Upvotes: 0
Views: 325
Reputation: 120638
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}
Upvotes: 1