code: def memoize(max_cache_size=1000):
      
      def wrapper(f):
          @wraps(f)
          def fn(*args, **kwargs):
              if kwargs:
                  key = (args, tuple(kwargs.items()))
              else:
                  key = args
              try:
                  return fn.cache[key]
              except KeyError:
                  if fn.count >= max_cache_size:
                      fn.cache = {}
                      fn.count = 0
                  result = f(*args, **kwargs)
                  fn.cache[key] = result
                  fn.count += 1
                  return result
              except TypeError:
                  return f(*args, **kwargs)
          fn.cache = {}
          fn.count = 0
          return fn
      return wrapper
docs: Python 2.4 compatible memoize decorator.
      It creates a cache that has a maximum size.  If the cache exceeds the max,
      it is thrown out and a new one made.  With such behavior, it is wise to set
      the cache just a little larger that the maximum expected need.
  
      Parameters:
        max_cache_size - the size to which a cache can grow