是否有与 dict 具有相同功能的 Python 持久数据存储(或如何哄骗“Shelf”来获得它)?
Posted
技术标签:
【中文标题】是否有与 dict 具有相同功能的 Python 持久数据存储(或如何哄骗“Shelf”来获得它)?【英文标题】:Is there a Python persitent data store that has the same functionality as dict (or how to coax "Shelve" to get that)? 【发布时间】:2011-03-20 08:44:57 【问题描述】:我正在使用 Python 3。shelve
在文档中被宣传为dict
的持久版本。但是,在我的使用中,事实证明 shelve
不允许元组作为键,而 dict 允许:
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'
【问题讨论】:
如果您的元组由简单的数据类型(如字符串)组成——如您的示例所示——您也许可以只使用它们的字符串表示作为键,例如 'db[repr((" word1", "word2"))] = 15`. 【参考方案1】:the shelve
module documentation中的第一段:
一个“架子”是一个持久的, 类字典对象。区别 使用“dbm”数据库是 书架中的值(不是键!)可以 本质上是任意的 Python 物体——任何泡菜 模块可以处理。这包括大部分 类实例,递归数据类型, 和包含大量共享的对象 子对象。 按键很普通 字符串。
[强调我的]
yaml
module 允许元组作为键:
>>> 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
【讨论】:
感谢您的回答,我没有仔细阅读该段。当 sehelve 没有按预期工作时,我只是跳到了 shelve 模块的限制部分,看看是否有任何关于它的内容,没有。无论如何:yaml 与 pickle 模块相比有什么优势?这个任务的唯一区别似乎是pickle使用二进制表示,而yaml使用字符串表示,对吧? @Anas Elghafari:优点:yaml 是人类可读的;泡菜在标准库中。你不应该对来自不受信任来源的数据调用.load()
。【参考方案2】:
元组在 Python 2.7.1 版本的 shelve
中也不能用作键。 2.7.1 documention 建议查看 ActiveState Persistent dictionary recipe。我对其进行了测试,它似乎可以使用元组作为键,如您的示例代码所示,格式为'csv'
,尽管不是'jason'
格式(我没有尝试'pickle'
)。如果你看一下食谱,你就会明白我所说的“格式”是什么意思。
【讨论】:
【参考方案3】:在我看来,搁置无法序列化元组以写入文件。
考虑pickle
作为替代方案。
【讨论】:
【参考方案4】:您可以使用dumps
和loads
将您的元组转换为字符串,然后再将它们用作搁架中的键。或者,如果您的元组仅包含文字,您可以使用 repr(your_tuple)
获取一个字符串表示,您可以使用 literal_eval
将其转换回元组。
为了使转换更方便,您可以继承 Shelf
并覆盖 __getitem__
和 __setitem__
以在访问时自动进行转换。
【讨论】:
以上是关于是否有与 dict 具有相同功能的 Python 持久数据存储(或如何哄骗“Shelf”来获得它)?的主要内容,如果未能解决你的问题,请参考以下文章
Scala 中是不是有与 Python 更通用的 map 函数等价的功能?