shelve对象和Python字典
我不确定这是不是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)
来修改这个默认设置,想了解更多细节可以查看文档。