Shelve doesn't act extactly the same as dictionary, notably when modifying objects that are already in the dictionary.
The difference is that when you add a class to a dictionary a reference is stored, but shelve keeps a pickled (serialized) copy of the object. If you then modify the object you will
modify the in-memory copy, but not the pickled version. That can be handled (mostly) transparently by shelf.sync()
and shelf.close()
,
which write out entries. Making all that work does require tracking all retrieved objects which haven't been written back yet so you do have to call shelf.sync() to clear the cache.
The problem with shelf.sync()
clearing the cache is that you can keep a reference to the object and modify it again.
This code doesn't work as expected with a shelf, but will work with a dictionary:
s["foo"] = MyClass()
s["foo"].X = 8
p = s["foo"] # store a reference to the object
p.X = 9 # update the reference
s.sync() # flushes the cache
p.X = 0
print "value in memory: %d" % p.X # prints 0
print "value in shelf: %d" % s["foo"].X # prints 9
Sync flushes the cache so the modified 'p' object is lost from the cache so it isn't written back.