Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a line in this python function necessary? (memoized recursion)

I got the following code snippet from Peter Norvig's website; it's a decorator to enable memoization on function calls (caching prior calls to the function to change an exponential recursion into a simple dynamic program).

def memo(f):
    table = {}
    def fmemo(*args):
        if args not in table:
            table[args] = f(*args)
        return table[args]
    fmemo.memo = table
    return fmemo

The code works fine, but I'm wondering why the second to last line is necessary. This is clearly a gap in my knowledge of Python, but removing the line and running a simple fibonacci function, it still seems to work. Does this have to do with memoizing multiple functions simultaneously? Why would the member variable of fmemo be called memo (assuming it's not an awkward coincidence)?

Thanks!

like image 481
JeremyKun Avatar asked Dec 17 '11 02:12

JeremyKun


1 Answers

Since functions are objects just like anything else, you can set attributes on them. See:

>>> def foo(): pass
>>> foo.x = 1
>>> foo.x
1

The second-to-line sets the internal cache of values as an attribute on the function object, thus exposing it. This means that you can take a memoised function and fiddle with its cache as you will, without having to call it. This might be convenient.


Example:

>>> @memo
... def id(x): return x
>>> id(1)
1
>>> id(2)
2
>>> id.memo
{(2,): 2, (1,): 1}
like image 198
Katriel Avatar answered Sep 27 '22 22:09

Katriel