有没有功能与字典相同的Python持久数据存储?(或者如何让"Shelve"达到那个效果?)

2 投票
4 回答
1216 浏览
提问于 2025-04-16 14:03

我正在使用Python 3。文档里说shelve是一个可以长期保存的版本的dict(字典)。不过在我使用的时候发现,shelve不允许用元组作为键,而字典是可以的:

import shelve
def tryShelve():
    db = shelve.open("shelvefile")
    db["word1"] = 1
    db[("word1", "word2")] = 15

tryShelve()

这会产生这个错误:

Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    tryShelve()
  File "<pyshell#40>", line 4, in tryShelve
    db[("word1", "word2")] = 15
  File "C:\Python32\lib\shelve.py", line 125, in __setitem__
    self.dict[key.encode(self.keyencoding)] = f.getvalue()
AttributeError: 'tuple' object has no attribute 'encode'

4 个回答

2

在Python 2.7.1版本的shelve中,元组(tuples)也不能作为键使用。2.7.1的文档建议查看ActiveState的持久字典的例子。我测试过这个例子,发现使用元组作为键是可以的,就像你在示例代码中用'csv'格式那样,不过在'jason'格式下就不行(我也没有尝试过'pickle'格式)。如果你查看这个例子,你就会明白我说的'格式'是什么意思。

4

这个shelve模块的文档中,第一段是这样说的:

“shelf”是一个持久化的、像字典一样的对象。它和“dbm”数据库的不同之处在于,在shelf中,值(而不是键!)可以是几乎任何Python对象——只要是pickle模块能处理的东西。这包括大多数类的实例、递归数据类型,以及包含很多共享子对象的对象。而键则是普通的字符串。

[强调是我加的]

yaml模块允许使用元组作为键:

>>> d = {}
>>> d["word1"] = 1
>>> d[("word1", "word2")] = 15
>>> import yaml
>>> yaml.dump(d)
'word1: 1\n? !!python/tuple [word1, word2]\n: 15\n'
>>> yaml.load(_)
{('word1', 'word2'): 15, 'word1': 1}
1

我觉得 shelve 这个工具不能把元组(tuple)保存成文件。
你可以考虑用 pickle 作为替代方案。

撰写回答