Memoization and encapsulation

Steven D'Aprano steve at REMOVETHIScyber.com.au
Fri Dec 30 23:23:26 EST 2005


I was playing around with simple memoization and came up with something
like this:

_cache = {}
def func(x):
    global _cache
    if _cache.has_key(x): 
        return _cache[x]
    else:
        result = x+1  # or a time consuming calculation...
        _cache[x] = result
        return result

when it hit me if I could somehow bind the cache to the function, I could
get rid of that pesky global variable.

I tried this:

>>> def func(x):
...     try:
...             func.cache
...     except AttributeError:
...             func.cache = {}
...     if func.cache.has_key(x):
...             return func.cache[x]
...     else:
...             result = x + 1
...             func.cache[x] = result
...             return result

and it works as expected, but it lacks elegance. 

Instead of using a function, I can also use a new-style class as if it
were a function:

>>> class Func(object):
...     cache = {}
...     def __new__(self, x):
...             if self.cache.has_key(x):
...                     return self.cache[x]
...             else:
...                     result = x+1
...                     self.cache[x] = result
...                     return result

and again it works, but I can't help feeling it is an abuse of the class
mechanism to do this.

What do folks think? Is there a better way?



-- 
Steven.




More information about the Python-list mailing list