Mutating Objects with shelve
Credit: Luther Blissett
Problem
You are using the standard module
shelve, some of the values you have shelved are
mutable objects, and you need to mutate these objects.
Solution
The shelve module, which offers a kind of
persistent dictionary, occupies an important niche between the power
of relational-database engines and the simplicity of
marshal, pickle,
dbm, and similar file formats. However,
there’s a typical trap that you need to avoid when
using shelve. Consider the following:
>>> import shelve
>>> # Build a simple sample shelf
>>> she=shelve.open('try.she', 'c')
>>> for c in 'spam': she[c]={c:23}
...
>>> for c in she.keys( ): print c, she[c]
...
p {'p': 23}
s {'s': 23}
a {'a': 23}
m {'m': 23}
>>> she.close( )We’ve created the shelve object,
added some data to it, and closed it. Now we can reopen it and work
with it:
>>> she=shelve.open('try.she','c')
>>> she['p']
{'p': 23}
>>> she['p']['p'] = 42
>>> she['p']
{'p': 23}What’s going on here? We just set the value to 42,
but it didn’t take in the shelve
object. The problem is that we were working with a temporary object
that shelve gave us, but shelve
doesn’t track changes to the temporary object. The
solution is to bind a name to this temporary object, do our mutation,
and then assign the mutated object back to the appropriate item of
shelve:
>>> a = she['p']
>>> a['p'] = 42
>>> she['p'] = a
>>> she['p']
{'p': 42}
>>> she.close( )We can even verify the change:
>>> she=shelve.open('try.she','c') >>> for ...