在2.4中使用cPickle序列化array.array
我正在做一个基于Python 2.4的项目(这是一个嵌入式的Python项目,所以我不能选择使用其他版本的Python)。在这个应用程序中,我们使用array.array
来存储数据。
在Python 2.5中,pickle
(还有cPickle
)增加了对array.array
对象的支持。在2.4版本中,我们有一个可行的解决办法,就是使用纯Python的pickle类(我们通过继承Pickler和Unpickler来处理数组),但这个方法在cPickle中不适用(我们需要使用cPickle是因为性能问题)。
有没有什么建议?
4 个回答
1
我不太确定数组类型是否可以通过添加一个 __reduce__
方法来扩展(可能需要用到子类),不过你可以尝试把数组转换成序列,然后再转换回来……如果内置的扩展机制对你不起作用的话。(这算是一种小技巧)
我之前没有尝试过这个,但你可以试试通过 copy_reg 来添加支持……这基本上和在你自己的类或子类中实现 __reduce__
得到的效果是一样的,只是稍微干净一点。
1
看起来你可以把它们“腌制”起来,但你不能把结果“腌制”回来。
Python 2.4.5 (#2, Jan 21 2010, 20:05:55)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cPickle as pickle
>>> import array
>>> a=array.array('i','12345678')
>>> pickle.dumps(a,2)
'\x80\x02carray\narray\nq\x01)\x81q\x02.'
>>> b=pickle.loads(_)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: array() takes at least 1 argument (0 given)
看起来这个“转储”的结果甚至没有包含类型代码的信息……甚至连数据都没有 :(
>>> a=array.array('c','abcdefghijkl')
>>> pickle.dumps(a,2)
'\x80\x02carray\narray\nq\x01)\x81q\x02.'
>>>
2
你可以使用标准库中的一个模块叫做 copy_reg,来注册一些函数,这样就能处理那些本身不支持被“打包”的类型的实例。cPickle
会在需要的时候使用你注册的这些函数。我建议你用这种“钩子”方法来满足你对 array.array
实例进行打包的需求。