Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store the result of an executed function and re-use later?

E.g., I have:

def readDb():
    # Fetch a lot of data from db, spends a lot time
    ...
    return aList

def calculation():
    x = readdb()
    # Process x
    ...
    return y

In the python interpreter,
each time I run calculation() it takes a lot of time to re-read the database, which is unnecessary.
How can I store the result from readdb() to avoid this reducdant process?

Edit:
I found a similar question here but I don't quite know the answer
Save functions for re-using without re-execution

like image 581
MK Yung Avatar asked Mar 19 '13 15:03

MK Yung


3 Answers

def readDb():
    ... #Fetch a lot of data from db, spends a lot time
    return aList

def calculation(data):
    x=data
    ...process x...
    return y

data = readDb()

calculation(data)
calculation(data)
calculation(data)

This will only hit the database once.

Basically, you want to save the results of readDb() to a seperate variable which you can then pass to calculation().

like image 115
zajd Avatar answered Nov 14 '22 21:11

zajd


Write a simple decorator:

class memo(object):
    def __init__(self, fun):
        self.fun = fun
        self.res = None
    def __call__(self):
        if self.res is None:
            self.res = self.fun()
        return self.res

@memo
def readDb():
    # ... etc
    return aList

For more general solutions, look here: http://code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/.

like image 29
djc Avatar answered Nov 14 '22 23:11

djc


Updated answer for modern Python

For anyone still searching for how to do this, the standard library functools includes a decorator function @functools.lru_cache to do this.

For example (from the docs):

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'http://www.python.org/dev/peps/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

This would store the last 32 calls to get_pep and when it is called with the same argument, the cached value will be returned.

like image 25
jmetz Avatar answered Nov 14 '22 23:11

jmetz