How can data remain persistent across multiple calls of decorated function?

Viewed 2782

The following function is meant to be used as a decorator that stores the results of already computed values. If the argument has already been calculated before, the function will return the value stored in the cache dictionary:

def cached(f):
    f.cache = {}
    def _cachedf(*args):
        if args not in f.cache:
            f.cache[args] = f(*args)

        return f.cache[args]

    return _cachedf

I realized (by mistake) that cache does not need to be an attribute of the function object. As a matter of facts, the following code works as well:

def cached(f):
    cache = {}   # <---- not an attribute this time!
    def _cachedf(*args):
        if args not in cache:
            cache[args] = f(*args)

        return cache[args]
    return _cachedf

I am having a hard time understanding how can the cache object be persistent across multiple calls. I tried calling multiple cached functions several times and could not find any conflict or problems.

Can anyone please help me understand how the cache variable still exists even after the _cachedf function is returned?

2 Answers
Related