想要更新/修改shelve中的键值

0 投票
1 回答
1789 浏览
提问于 2025-05-10 15:11

我有一组数据,比如 {'/domflight': 10, '/intlflight': 20},我想把 '/domflight' 的值改成 50。下面是我尝试写的代码,但没有成功。

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()

相关文章:

  • 暂无相关问题
暂无标签

1 个回答

3

Shelve 这个工具不能检测到嵌套的可变对象的变化。也就是说,如果你在一个嵌套的字典里设置一个键,它不会自动保存。

你需要重新设置整个字典:

nested_dict = s['key1']
nested_dict['/domflight'] = 50
s['key1'] = nested_dict

把值重新赋给 s['key1'] 这个操作才会触发保存。

从技术上讲,sUserDict.DictMixin 类的一个子类,并且有一个自定义的 __setitem__ 方法。当你直接给 s 对象里的键赋值时,会调用这个方法,从而保存变化。但是,如果你在一个键下的可变对象上进行赋值,这个操作不会触发 __setitem__ 方法,所以变化就不会被检测到,也就不会保存。

这个问题在 文档中有说明

由于 Python 的特性,shelf 不能知道一个可变的持久字典条目何时被修改。默认情况下,只有在将对象赋值给 shelf 时,修改过的对象才会被写入(见 示例)。如果可选的 writeback 参数设置为 True,那么所有被访问的条目也会被缓存到内存中,并在 sync()close() 时写回;这可以让你在持久字典中更方便地修改可变条目,但如果访问的条目很多,可能会消耗大量的内存来存储缓存,并且关闭操作会变得非常慢,因为所有被访问的条目都要写回(没有办法判断哪些被访问的条目是可变的,也不知道哪些实际上被修改过)。

撰写回答