Reputation: 4960
I have a data (i.e {'/domflight': 10, '/intlflight': 20}
) and want to modify the value of '/domflight'
to 50
. Below is my code which I am trying to do but no luck.
import shelve
s = shelve.open('/tmp/test_shelf.db')
try:
print s['key1']
s['key1']['/domflight'] = 50
finally:
s.close()
s = shelve.open('/tmp/test_shelf.db', writeback=True)
try:
print s['key1']
finally:
s.close()
Upvotes: 0
Views: 1910
Reputation: 1122172
Shelve cannot detect changes to nested mutable objects. Setting a key in a nested dictionary does not trigger a save.
Re-set the dictionary instead:
nested_dict = s['key1']
nested_dict['/domflight'] = 50
s['key1'] = nested_dict
It is the assignment back to s['key1']
that triggers a save.
Technically, what happens is that s
is a subclass of the UserDict.DictMixin
class with a custom __setitem__
method. Assigning directly to keys in the s
object calls that method an the change is saved. But assigning to a mutable object that is nested under a key will not trigger a call to __setitem__
, thus the change is not detected and nothing is saved.
This is covered in the documentation:
Because of Python semantics, a shelf cannot know when a mutable persistent-dictionary entry is modified. By default modified objects are written only when assigned to the shelf (see Example). If the optional writeback parameter is set to
True
, all entries accessed are also cached in memory, and written back onsync()
andclose()
; this can make it handier to mutate mutable entries in the persistent dictionary, but, if many entries are accessed, it can consume vast amounts of memory for the cache, and it can make the close operation very slow since all accessed entries are written back (there is no way to determine which accessed entries are mutable, nor which ones were actually mutated).
Upvotes: 3