I'm trying to make an object act like a built-in list
, except that its value be saved once modified.
The implementation I come up with is wrapping a list
in a PersistentList
class. For every access to method that may change the list, the wrapper delegates to the wrapped list
, and save it to a key-value database after it's invoked.
Code:
class PersistentList(object):
def __init__(self, key):
self.key = key
self._list = db.get(key, [])
def __getattr__(self, name):
attr = getattr(self._list, name)
if attr:
if attr in ('append', 'extend', 'insert', 'pop',
'remove', 'reverse', 'sort'):
attr = self._autosave(attr)
return attr
raise AttributeError
def _autosave(self, func):
@wraps(func)
def _(*args, **kwargs):
ret = func(*args, **kwargs)
self._save()
return ret
return _
def _save(self):
db.set(self.key, self._list)
There are several problems with this implementation:
I have to decorate methods like append
every time they are
accessed, is there a better way to decorate multiple methods of some
object?
Operations like l += [1,2,3]
don't work because I haven't
implemented the iadd method.
What can I do to simplify this?
I like @andrew cooke's answer but I see no reason why you can't derive directly from a list.
class PersistentList(list):
def __init__(self, *args, **kwargs):
for attr in ('append', 'extend', 'insert', 'pop', 'remove', 'reverse', 'sort'):
setattr(self, attr, self._autosave(getattr(self, attr))
list.__init__(self, *args, **kwargs)
def _autosave(self, func):
@wraps(func)
def _func(*args, **kwargs):
ret = func(*args, **kwargs)
self._save()
return ret
return _func
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With