shelve对象和Python字典

-1 投票
2 回答
693 浏览
提问于 2025-04-18 13:49

我不确定这是不是shelve对象的一个bug,但这种行为确实有点奇怪。如果你把一个字典对象存储在shelve对象里,似乎你不能轻松地修改这个字典。下面有一段Python代码来演示这个问题:

>>> import shelve
>>> d=shelve.open('test')
>>> d['test'] = {'test1':'A' }
>>> print d['test']['test1']
A
>>> d['test']['test1'] = 'C'
>>> print d['test']['test1']
A # !!! odd
>>> d['test'] = {'test1':'A' }
>>> d1 = d['test']
>>> d1['test1'] = 'C'
>>> print d1
{'test1': 'C'}
>>> d['test']= d1
>>> print d['test']['test1']
C
>>> d['test'] = {'test1':'A' }
>>> d['test'] = {'test1':'C' }
>>> print d['test']['test1']
C

这是Python中shelve对象的正常行为吗?

2 个回答

0

希望能更好地解释

Python的shelve模块是一个键/值存储。

这基本上意味着它的工作方式像一个Python字典(确实如此)。但是当你执行以下操作时:

from shelve import open

d = open("test.db")
d["a"] = {"b": 1}

你实际上是在存储以下内容:

  • 键:"a"
  • 值:{"b": 1}

当你接着询问这个“存储”关于键a的信息时,你会立即得到值{"b": 1},这个值在内存中现在是一个新的对象引用(dict)。

所以接下来这个操作不会存储或改变存储中的值:

d["a"]["b"] = 2

这只会改变你隐式引用的“内存中”的字典{"b": 1}

要在键a中存储一个新的值{"b": 1},你必须“明确”地为a设置一个新的值,如下所示:

d["a"] = {"b": 2}
2

根据文档的说明,

      d[key] = data   # store data at key (overwrites old data if
                      # using an existing key)

      data = d[key]   # retrieve a COPY of the data at key (raise
                      # KeyError if no such key) -- NOTE that this
                      # access returns a *copy* of the entry!

在你的代码中,d['test']= d1 这个操作会改变原来的数据,而 d['test']['test1'] = 'C' 则会改变新复制的对象。你可以使用 d = shelve.open('test', writeback=True) 来修改这个默认设置,想了解更多细节可以查看文档。

撰写回答