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