7

我想做的就是序列化和反序列化字符串或整数的元组。

我查看了 pickle.dumps() 但字节开销很大。基本上,它看起来占用的空间大约是它需要的 4 倍。此外,我只需要基本类型,不需要序列化对象。

marshal 在空间方面稍微好一点,但结果充满了讨厌的 \x00 字节。理想情况下,我希望结果是人类可读的。

我想只使用 repr() 和 eval(),但有没有一种简单的方法可以在不使用 eval() 的情况下完成此操作?

这是存储在数据库中,而不是文件中。字节开销很重要,因为它可能会在需要 TEXT 列和 varchar 之间产生差异,并且通常数据紧凑性会影响数据库性能的所有领域。

4

7 回答 7

13

看看json,至少生成dumps的可以用许多其他语言读取。

JSON(JavaScript Object Notation)http://json.org是 JavaScript 语法(ECMA-262 第 3 版)的子集,用作轻量级数据交换格式。

于 2009-02-10T16:28:58.917 回答
8

我个人会使用yaml。它在编码大小方面与 json 相当,但在必要时它可以表示一些更复杂的事物(例如类、递归结构)。

In [1]: import yaml
In [2]: x = [1, 2, 3, 'pants']
In [3]: print(yaml.dump(x))
[1, 2, 3, pants]

In [4]: y = yaml.load('[1, 2, 3, pants]')
In [5]: y
Out[5]: [1, 2, 3, 'pants']
于 2009-02-10T16:47:10.980 回答
8

也许您没有使用正确的协议:

>>> import pickle
>>> a = range(1, 100)
>>> len(pickle.dumps(a))
492
>>> len(pickle.dumps(a, pickle.HIGHEST_PROTOCOL))
206

请参阅pickle 数据格式的文档。

于 2009-02-10T17:39:57.187 回答
6

如果您需要节省空间的解决方案,您可以使用 Google 协议缓冲区。

协议缓冲区 - 编码

协议缓冲区 - Python 教程

于 2009-02-10T17:14:10.680 回答
1

python 文档中提到了一些持久性内置函数,但我认为在生成的文件大小中没有任何一个明显更小。

你总是可以使用configparser,但你只能得到 string、int、float、bool。

于 2009-02-10T16:15:16.080 回答
0

“字节开销很大”

为什么这很重要?它完成了这项工作。如果您的磁盘空间不足,我很乐意以 500 美元的价格卖给您一个 1Tb。

你跑了吗?性能有问题吗?你能证明序列化的性能是问题吗?

“我想只使用 repr() 和 eval(),但有没有一种简单的方法可以在不使用 eval() 的情况下完成此任务?”

没有什么比 repr 和 eval 更简单的了。

评估有什么问题?

是“有人可以在我序列化列表的文件中插入恶意代码”的问题吗?

谁——特别是——会找到并编辑这个文件以放入恶意代码?您为保护这一点所做的任何事情(即加密)都会从中删除“简单”。

于 2009-02-10T16:15:50.570 回答
-1

幸运的是,有一个使用 COMPRESSION 的解决方案,并解决了涉及任意 Python 对象(包括新类)的一般问题。有时,与其对元组进行微观管理,不如使用 DRY 工具。
您的代码将更加清晰,并且在未来类似的情况下更容易重构。

y_serial.py 模块 :: 使用 SQLite 存储 Python 对象

“序列化 + 持久性 :: 在几行代码中,将 Python 对象压缩和注释为 SQLite;然后在没有任何 SQL 的情况下通过关键字按时间顺序检索它们。数据库存储无模式数据的最有用的“标准”模块。”

http://yserial.sourceforge.net

[如果您仍然担心,为什么不将这些元组放在字典中,然后将 y_serial 应用于字典。由于 zlib 在后台的透明压缩,任何开销都可能会消失。]

至于可读性,文档还详细说明了为什么选择 cPickle 而不是 json。

于 2009-09-17T08:09:07.503 回答