您的位置:首页 > 编程语言 > Python开发

python中序列化用法(pickle)

2014-04-22 19:28 656 查看
转自:http://www.pythonclub.org/modules/pickle

python核心模块pickle和cPickle讲解

pickle模块使用的数据格式是python专用的,并且不同版本不向后兼容,同时也不能被其他语言说识别。要和其他语言交互,可以使用内置的json 包使用pickle模块你可以把Python对象直接保存到文件,而不需要把他们转化为字符串,也不用底层的文件访问操作把它们写入到一个二进制文件里。 pickle模块会创建一个python语言专用的二进制格式,你基本上不用考虑任何文件细节,它会帮你干净利落地完成读写独享操作,唯一需要的只是一个合法的文件句柄。


pickle 主要函数

pickle模块中的两个主要函数是dump()和load()。dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。

dumps()函数执行和dump() 函数相同的序列化,但是与dump不同的dumps并不将转换后的字符串写入文件,而是将所得到的转换后的数据以字符串的形式返回。

loads()函数执行和load()函数一样的反序列化。 loads接受一个字符串参数,将字符串解码成为python的数据类型,函数loads和dumps进行的是互逆的操作。

cPickle是pickle得一个更快得C语言编译版本。

pickle的dump和load相当于java的序列化和反序列化操作


pickle用法示例

#! /usr/local/env python
# -*- coding=utf-8 -*-

if __name__ == "__main__":
import cPickle

#序列化到文件
obj = 123,"abcdedf",["ac",123],{"key":"value","key1":"value1"}
print obj
#输出:(123, 'abcdedf', ['ac', 123], {'key1': 'value1', 'key': 'value'})
#r 读写权限 r b 读写到二进制文件
f = open(r"d:\a.txt","r ")
cPickle.dump(obj,f)
f.close()
f = open(r"d:\a.txt")
print cPickle.load(f)
#输出:(123, 'abcdedf', ['ac', 123], {'key1': 'value1', 'key': 'value'})

#序列化到内存(字符串格式保存),然后对象可以以任何方式处理如通过网络传输
obj1 = cPickle.dumps(obj)
print type(obj1)
#输出:<type 'str'>
print obj1
#输出:python专用的存储格式
obj2 = cPickle.loads(obj1)
print type(obj2)
#输出:<type 'tuple'>
print obj2
#输出:(123, 'abcdedf', ['ac', 123], {'key1': 'value1', 'key': 'value'})


当然啦,你dump几次,也就是需要load几次,不要希望dump了三次,load给你返回一个list。

转自:http://oldj.net/article/python-pickle/


Python中使用pickle持久化对象

Python中可以使用 pickle 模块将对象转化为文件保存在磁盘上,在需要的时候再读取并还原。具体用法如下:

pickle.dump(obj, file[, protocol])

这是将对象持久化的方法,参数的含义分别为:

obj: 要持久化保存的对象;

file: 一个拥有 write() 方法的对象,并且这个 write() 方法能接收一个字符串作为参数。这个对象可以是一个以写模式打开的文件对象或者一个
StringIO 对象,或者其他自定义的满足条件的对象。

protocol: 这是一个可选的参数,默认为 0 ,如果设置为 1 或 True,则以高压缩的二进制格式保存持久化后的对象,否则以ASCII格式保存。

对象被持久化后怎么还原呢?pickle 模块也提供了相应的方法,如下:

pickle.load(file)

只有一个参数 file ,对应于上面 dump 方法中的 file 参数。这个 file 必须是一个拥有一个能接收一个整数为参数的 read() 方法以及一个不接收任何参数的 readline() 方法,并且这两个方法的返回值都应该是字符串。这可以是一个打开为读的文件对象、StringIO
对象或其他任何满足条件的对象。

下面是一个基本的用例:

1234567891011121314151617# -*- coding: utf-8 -*- import pickle# 也可以这样:# import cPickle as pickle obj = {"a": 1, "b": 2, "c": 3} # 将 obj 持久化保存到文件 tmp.txt 中pickle.dump(obj, open("tmp.txt", "w")) # do something else ... # 从 tmp.txt 中读取并恢复 obj 对象obj2 = pickle.load(open("tmp.txt", "r")) print obj2
不过实际应用中,我们可能还会有一些改进,比如用 cPickle 来代替 pickle ,前者是后者的一个 C 语言实现版本,拥有更快的速度,另外,有时在 dump 时也会将第三个参数设为 True 以提高压缩比。再来看下面的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

#
-*- coding: utf-8 -*-

import
cPickle
as
pickle

import
random

import
os

import
time

LENGTH
=
1024
*
10240

def
main():

d
=
{}

a
=
[]

for
i
in
range(LENGTH):

a.append(random.randint(0,
255))

d["a"]
=
a

print
"dumping..."

t1
=
time.time()

pickle.dump(d,
open("tmp1.dat",
"wb"),
True)

print
"dump1:
%.3fs"
%
(time.time()
-
t1)

t1
=
time.time()

pickle.dump(d,
open("tmp2.dat",
"w"))

print
"dump2:
%.3fs"
%
(time.time()
-
t1)

s1
=
os.stat("tmp1.dat").st_size

s2
=
os.stat("tmp2.dat").st_size

print
"%d,
%d,
%.2f%%"
%
(s1,
s2,
100.0
*
s1
/
s2)

print
"loading..."

t1
=
time.time()

obj1
=
pickle.load(open("tmp1.dat",
"rb"))

print
"load1:
%.3fs"
%
(time.time()
-
t1)

t1
=
time.time()

obj2
=
pickle.load(open("tmp2.dat",
"r"))

print
"load2:
%.3fs"
%
(time.time()
-
t1)

if
__name__
==
"__main__":

main()

在我的电脑上执行结果为:

dumping…

dump1: 1.297s

dump2: 4.750s

20992503, 68894198, 30.47%

loading…

load1: 2.797s

load2: 10.125s

可以看到,dump 时如果指定了 protocol 为 True,压缩过后的文件的大小只有原来的文件的 30% ,同时无论在 dump 时还是 load 时所耗费的时间都比原来少。因此,一般来说,可以建议把这个值设为 True 。

另外,pickle 模块还提供 dumps 和 loads 两个方法,用法与上面的 dump 和 load 方法类似,只是不需要输入 file 参数,输入及输出都是字符串对象,有些场景中使用这两个方法可能更为方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: