设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 39246|回复: 7
打印 上一主题 下一主题

【Python 第65课】pickle

[复制链接]

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2014-5-5 18:33:55 |显示全部楼层 |倒序浏览

在之前的课程中,我们有讲到通过文件来保存、中转数据(参见第31、32、33课)。在使用文件存储时,通常需要对数据进行一些处理,按照一定的规范把数据整理成文本,再写入文件中。下次使用时,从文件中读出文本,再按照此规范解析这些数据。

这种将数据转成文本的过程又被称为“序列化”,即将对象状态转换为可保持或传输的格式的过程。对应的,从序列化的格式中解析对象状态的过程被称为“反序列化”。

在之前的课程和示例中,我们都自己手动实现了这个过程。其实 Python 提供了一个标准模块来做这件事,就是 pickle。它可以把任何 Python 对象存储在文件中,再把它原样取出来。

来看一下存储的过程:

import pickle

test_data = ['Save me!', 123.456, True]

f = file('test.data', 'w')
pickle.dump(test_data, f)
f.close()

这样,我们就把 test_data 这个 list 存储在了文件 test.data 中。你可以用文本编辑器打开 test.data 查看里面的内容:

(lp0
S'Save me!'
p1
aF123.456
aI01
a.

这就是经 pickle 序列化后的数据,隐约可以看到之前对象的影子。你可能无法看出这个文件的规律,这没关系,Python 能看懂就可以了。

下面取存储的过程:

import pickle

f = file('test.data')
test_data = pickle.load(f)
f.close()

print test_data

控制台的输出:

['Save me!', 123.456, True]

和存储前的数据是一致的。


如果你想保存多个对象,一种方法是把这些对象先全部放在一个序列中,在对这个序列进行存储:

a = 123
b = "hello"
c = 0.618
data = (a, b, c)
...
pickle.dump(data, f)

另一种方法就是依次保存和提取:

...
pickle.dump(a, f)
pickle.dump(b, f)
pickle.dump(c, f)
...
x = pickle.load(f)
y = pickle.load(f)
z = pickle.load(f)


dump 方法可以增加一个可选的参数,来指定用二进制来存储:

pickle.dump(data, f, True)

而 load 方法会自动检测数据是二进制还是文本格式,无需手动指定。


Python 还提供了另一个模块 cPickle,它的功能及用法和 pickle 模块完全相同,只不过它是用C语言编写的,因此要快得多(比pickle快1000倍)。因此你可以把上述代码中的 pickle 全部替换为 cPickle,从而提高运行速度(尽管在这个小程序中影响微乎其微)。


#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

沙发
发表于 2016-2-22 12:56:41 |显示全部楼层
catherinemic 发表于 2016-2-21 21:26
crossin老师,学习了pickle以后,有个疑问,直接把数据存入txt文件不是也可以吗?因为尝试应用pickle到猜数 ...

你自己做读写的处理是可以。但是复杂的对象,用pickle不是省事吗,又不用自己写处理,只要dump和load就可以了
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

板凳
发表于 2016-4-15 11:23:57 |显示全部楼层
exchen 发表于 2016-4-14 18:29
老师运行你代码提示AttributeError: 'module' object has no attribute 'dump'是为啥?

不知道,看不到代码我猜不出。可能你有地方写错了,也可能你把文件保存成了叫 pickle.py
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

地板
发表于 2017-8-26 13:02:55 |显示全部楼层
blueheart 发表于 2017-8-25 12:42
老师运行你代码提示AttributeError: 'module' object has no attribute 'dump'是为啥?

文件夹里面是不是有别的文件被你命名成了 pickle.py
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

5#
发表于 2017-8-26 13:03:42 |显示全部楼层
blueheart 发表于 2017-8-25 12:42
老师运行你代码提示AttributeError: 'module' object has no attribute 'dump'是为啥?

应该还是一样的命名问题吧,检查下别的文件
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

6#
发表于 2017-12-17 15:33:07 |显示全部楼层
很好吃 发表于 2017-12-16 12:52
crossin先生,我只有这样写才能达到你说的效果
import pickle

因为 dump 出来的结果不是可读文本,类型不对
你这应该是 py3 的变动
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

7#
发表于 2017-12-22 14:19:19 |显示全部楼层
敦敦敦 发表于 2017-12-21 10:37
请问一下我这边什么地方出问题了

open也要b模式
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

8#
发表于 2018-9-16 15:25:06 |显示全部楼层
laotianpeng 发表于 2018-9-15 20:41
老师您好!我用的是python3.7,学到这里总是报错:
Traceback (most recent call last):
  File "C:/Users/ ...

改成 open('somefile.data','wb')
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-11-1 08:34 , Processed in 0.023654 second(s), 22 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部