new style shelve implementation

Nicholas Wieland nicholas_wieland at
Sat Jan 3 03:34:55 CET 2004

I'm using the shelve module for a program I'm writing, and reading the
source I've noted that shelve doesn't use new style classes.
Well, this is the first time I use *seriously* new style classes (I work
primarly on Zope and Python 2.1), so the result is probably far from
production code, but after half an hour of hacking my Shelf class seems to
work like the original one (much more than what I expected...) :)

class Shelf (dict):
        def __init__ (self, dict, protocol = None, writeback = False, binary = None):
                self.dict = dict
                if protocol is not None and binary is not None:
                        raise ValueError, "can't specifiy both 'protocol' and 'binary'"
                if binary is not None:
                        warnings.warn ("The 'binary' argument to Shelf() is deprecated",
                        protocol = int (binary)
                if protocol is None:
                        protocol = 0
                self.protocol = protocol
                self.writeback = writeback
                self.cache = {}
        def __repr__ (self):
                dummy = dict ()
                for k in self.keys ():
                        dummy [k] = self [k]
                return repr (dummy)
        def keys (self):
                return self.dict.keys ()
        def __len__ (self):
                return len (self)
        def has_key (self, key):
                return self.dict.has_key (key)
        def __contains__ (self, key):
                return self.has_key (key)
        def get (self, key, default = None):
                if self.has_key (key):
                        return self.dict [key]
                return default
        def __getitem__ (self, key):
                        value = self.cache [key]
                except KeyError:
                        f = StringIO (self.dict [key])
                        value = Unpickler (f).load ()
                        if self.writeback:
                                self.cache [key] = value
                return value
        def __setitem__ (self, key, value):
                if self.writeback:
                        self.cache [key] = value
                f = StringIO ()
                p = Pickler (f, self.protocol)
                p.dump (value)
                self.dict [key] = f.getvalue ()
        def __delitem__ (self, key):
                del self.dict [key]
                        del self.cache [key]
                except KeyError:
        def close (self):
                self.sync ()
                        self.dict.close ()
                except AttributeError:
                self = None
        def __del__ (self):
                self.close ()
        def sync (self):
                if self.writeback and self.cache:
                        self.writeback = False
                        for key, entry in self.cache.iteritems ():
                                self.dict [key] = entry
                        self.writeback = True
                        self.cache = {}
                if hasattr (self.dict, "sync"):
                        self.sync ()
Everything else is like the original one, I've just added a totally
unpythonic implementation of the __repr__ method and removed the UserDict
IMVHO if UserDict is going to be removed it's good to start removing
it from the python library.
On the other hand, this is just a dirty hack, so every comment is deeply

Happy new year,

More information about the Python-list mailing list