regarding memoize function
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Fri Apr 4 02:56:37 EDT 2008
En Fri, 04 Apr 2008 02:24:14 -0300, <ankitks.mital at gmail.com> escribió:
> On Apr 3, 8:04 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar> wrote:
>> En Thu, 03 Apr 2008 21:21:11 -0300, Dan Bishop <danb... at yahoo.com>
>> escribió:
>> > On Apr 3, 6:33 pm, ankitks.mi... at gmail.com wrote:
>> >> I saw example of memoize function...here is snippet
>>
>> >> def memoize(fn, slot):
>> >> def memoized_fn(obj, *args):
>> >> if hasattr(obj, slot):
>> >> return getattr(obj, slot)
>> >> else:
>> >> val = fn(obj, *args)
>> >> setattr(obj, slot, val)
>> >> return val
>> >> return memoized_fn
>>
> Thanks Gabriel and Dan,
> But I am still confuse on...
> what is obj?
>
> Let say
> def f(node): return max(node.path_cost+h(node), getattr(node, 'f', -
> infinity))
> f = memoize(f,'f')
>
> what is this doing?
> I am passing string 'f' as second argument? right? so evertime in
> function memoize,
> I am doing hasattr(obj, slot), I am saying hasattr(obj, 'f')?
>
> I kindof understand that I am returning maximum of pre-computed
> value(if there is already) vs. new calculation.
> But syntax is throwing me off.
It *is* confusing. And a bit strange that it does not use the args
argument as a key (if it is true that f(*args) doesn't depend on args, why
using args in the first place?)
You may be calling f as f(a,b,c) or as a.f(b,c) - in both cases, obj is
`a`, the first argument (or "self" when used as a method)
An alternative version (with the same limitations with regard to *args)
but usable as a mehtod decorator:
from functools import wraps
def memoize(slot):
def decorator(fn, slot=slot):
@wraps(fn)
def inner(self, *args):
if hasattr(self, slot):
return getattr(self, slot)
else:
val = fn(self, *args)
setattr(self, slot, val)
return val
return inner
return decorator
class Foo(object):
def __init__(self, items):
self.items = tuple(items)
@memoize('max')
def hardtocompute(self):
return max(self.items)
a = Foo((10,20,30))
assert not hasattr(a,'max')
assert a.hardtocompute()==30
assert a.max==30
del a.items
assert a.hardtocompute()==30
There is an excelent article by Michele Simionato explaining decorators
with some useful recipes.
http://www.phyast.pitt.edu/~micheles/python/documentation.html
--
Gabriel Genellina
More information about the Python-list
mailing list