Changeset 655 for branches


Ignore:
Timestamp:
04/04/13 16:28:27 (3 years ago)
Author:
mmckerns
Message:

abstracted serializer and memo in memoize.memoized; added db_memo

Location:
branches/decorate
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/decorate/memoize.py

    r621 r655  
    283283 
    284284 
    285 def memoized(): 
    286     """Decorator that memoizes a function's return value each time it is called. 
    287     If called later with the same arguments, the memoized value is returned, and 
    288     not re-evaluated.  This may lead to memory issues, as memo is never cleared. 
    289     """ 
    290     memo = {} 
    291  
    292     def dec(f): 
    293         def func(*args, **kwds): 
    294             try: 
    295                #import cPickle as pickle 
    296                 import dill as pickle 
    297                 argstr = pickle.dumps((args, kwds)) 
    298                 if not memo.has_key(argstr): 
    299                     memo[argstr] = f(*args, **kwds) 
    300                 return memo[argstr] 
     285#XXX: should inherit from object not dict ? 
     286class db_dict(dict): #XXX: requires UTF-8 key 
     287    """decorator that can memoize to a database (API mimics a dict) 
     288    """ 
     289    def __init__(self, database=None, table=None): 
     290        """database = database url; table = table name""" 
     291        if database == None: database = ':memory:' 
     292        self._database = database 
     293        if table == None: table = 'memo' 
     294        self._table = table 
     295        import sqlite3 as db 
     296        self._conn = db.connect(database) 
     297        self._curs = self._conn.cursor() 
     298        sql = "create table %s(argstr, fval)" % table 
     299        self._curs.execute(sql) 
     300        return 
     301    def __setitem__(self, key, value): #XXX: maintains 'history' of values 
     302        sql = "insert into %s values(?,?)" % self._table 
     303        self._curs.execute(sql, (key,value)) 
     304        self._conn.commit() 
     305        return 
     306    def __getitem__(self, key): 
     307        sql = "select * from %s where argstr = ?" % self._table 
     308        res = tuple(self._curs.execute(sql, (key,))) 
     309        if res: return res[-1][-1] # always get the last one 
     310        raise KeyError, key 
     311    def __asdict__(self): 
     312        sql = "select * from %s" % self._table 
     313        res = self._curs.execute(sql) 
     314        d = {} 
     315        [d.update({k:v}) for (k,v) in res] # always get the last one 
     316        return d 
     317    def has_key(self, key): 
     318        return key in self.keys() 
     319    def get(self, key, value): 
     320        return self.__asdict__().get(key, value) 
     321    def items(self): 
     322        return self.__asdict__().items() 
     323    def keys(self): 
     324        return self.__asdict__().keys() 
     325    def values(self): 
     326        return self.__asdict__().values() 
     327    def __repr__(self): 
     328        return "memo(%s)" % self.__asdict__() 
     329    pass 
     330 
     331 
     332def memoized(memo=None, serializer=str): 
     333    """Decorator that memoizes a function's return value each time it is called. 
     334    If called later with the same arguments, the memoized value is returned, and 
     335    not re-evaluated.  This may lead to memory issues, as memo is never cleared. 
     336 
     337    memo = storage hashmap (default is {}) 
     338    serializer = serializing function (e.g. pickle.dumps, but default is str) 
     339    """ 
     340    if memo == None: memo = dict() 
     341 
     342    def dec(f): 
     343        def func(*args, **kwds): 
     344            try: 
     345                argstr = serializer((args, kwds)) 
     346                if memo.has_key(argstr): 
     347                    return memo[argstr] 
     348                res = f(*args, **kwds) 
     349                memo[argstr] = res 
     350                return res 
    301351            except: #TypeError 
    302352                return f(*args, **kwds) 
     
    311361    not re-evaluated.  This may lead to memory issues, as memo is never cleared. 
    312362    """ 
    313     def __init__(self, func): 
     363    def __init__(self, func): #memo=None, serializer=str): 
    314364      self.func = func 
    315       self.memo = {} 
     365     #if memo == None: memo = dict() 
     366      self.memo = {} #memo 
     367      import cPickle as pickle 
     368      self.serializer = pickle.dumps #serializer 
    316369 
    317370    def __call__(self, *args, **kwds): 
    318371      try: 
    319          #import cPickle as pickle 
    320           import cPickle as pickle 
    321           argstr = pickle.dumps((args, kwds)) 
    322           if not self.memo.has_key(argstr): 
    323               self.memo[argstr] = self.func(*args, **kwds) 
     372        argstr = self.serializer((args, kwds)) 
     373        if self.memo.has_key(argstr): 
    324374          return self.memo[argstr] 
     375        res = self.func(*args, **kwds) 
     376        self.memo[argstr] = res 
     377        return res 
    325378      except: #TypeError 
    326           return self.func(*args, **kwds) 
     379        return self.func(*args, **kwds) 
    327380 
    328381    def __repr__(self): 
  • branches/decorate/test_memoize.py

    r601 r655  
    109109print costD([1,2,3.1234], 3.6789) 
    110110print costD([1,2,3.4321], 3.6789) 
     111print "" 
     112 
     113 
     114from memoize import memoized 
     115from memoize import db_dict  
     116import dill as pickle 
     117@memoized(memo=db_dict()) 
     118def add(x,y): 
     119    return x+y 
     120add(1,2) 
     121add(1,2) 
     122add(1,3) 
     123print "db_memo = %s" % add.memo 
     124 
     125@memoized(memo=dict()) 
     126def add(x,y): 
     127    return x+y 
     128add(1,2) 
     129add(1,2) 
     130add(1,3) 
     131print "dict_memo = %s" % add.memo 
     132 
     133@memoized(memo=add.memo) 
     134def add(x,y): 
     135    return x+y 
     136add(1,2) 
     137add(2,2) 
     138print "re_dict_memo = %s" % add.memo 
     139 
     140@memoized(serializer=pickle.dumps) 
     141def add(x,y): 
     142    return x+y 
     143add(1,2) 
     144add(1,2) 
     145add(1,3) 
     146print "pickle_dict_memo = %s" % add.memo 
    111147 
    112148 
Note: See TracChangeset for help on using the changeset viewer.