设为首页收藏本站

Crossin的编程教室

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

【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
回复

使用道具 举报

0

主题

0

好友

22

积分

新手上路

Rank: 1

26#
发表于 2018-10-22 19:19:55 |只看该作者
没有乱码,不好意思!
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

25#
发表于 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
回复

使用道具 举报

0

主题

0

好友

8

积分

新手上路

Rank: 1

24#
发表于 2018-9-15 20:41:30 |只看该作者
老师您好!我用的是python3.7,学到这里总是报错:
Traceback (most recent call last):
  File "C:/Users/Laotianpeng/Desktop/pythonlearn/t1.py", line 4, in <module>
    pickle.dump(test_data,f)
TypeError: write() argument must be str, not bytes
我的代码是:
import pickle
test_data=["Save me !",'123.456',True]
with open('somefile.data','w') as f:
    pickle.dump(test_data,f)
   
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

23#
发表于 2017-12-22 14:19:19 |只看该作者
敦敦敦 发表于 2017-12-21 10:37
请问一下我这边什么地方出问题了

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

使用道具 举报

1

主题

0

好友

35

积分

新手上路

Rank: 1

22#
发表于 2017-12-21 10:37:35 |只看该作者
请问一下我这边什么地方出问题了
  1. import pickle

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

  3. f=open('test.data','wb')
  4. pickle.dump(test_data, f)
  5. f.close()



  6. import pickle

  7. f = open('test.data')
  8. test_data = pickle.load(f)
  9. f.close()

  10. print (test_data)



  11. C:\Users\lenovo\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/lenovo/AppData/Local/Programs/Python/Python37-32/DLLs/asdfghjkkjhgxcvbnm,
  12. Traceback (most recent call last):
  13.   File "C:/Users/lenovo/AppData/Local/Programs/Python/Python37-32/DLLs/asdfghjkkjhgxcvbnm,", line 14, in <module>
  14.     test_data = pickle.load(f)
  15. UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 0: illegal multibyte sequence

  16. Process finished with exit code 1
复制代码
回复

使用道具 举报

0

主题

0

好友

22

积分

新手上路

Rank: 1

21#
发表于 2017-12-18 09:08:58 |只看该作者
crossin先生 发表于 2017-12-17 15:33
因为 dump 出来的结果不是可读文本,类型不对
你这应该是 py3 的变动

好的,的确是py3,谢谢老师回复
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

20#
发表于 2017-12-17 15:33:07 |只看该作者
很好吃 发表于 2017-12-16 12:52
crossin先生,我只有这样写才能达到你说的效果
import pickle

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

使用道具 举报

0

主题

0

好友

22

积分

新手上路

Rank: 1

19#
发表于 2017-12-16 12:52:17 |只看该作者
crossin先生,我只有这样写才能达到你说的效果
import pickle

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

f = open("test.data", "wb")
pickle.dump(test_data, f)
f.close()


import pickle

f = open("test.data","rb")
test_data = pickle.load(f)
f.close()

print (test_data)

如果不用wb和rb就报错
TypeError: write() argument must be str, not bytes
以及TypeError: a bytes-like object is required, not 'str'
请问这是什么原理呢
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

18#
发表于 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
回复

使用道具 举报

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

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

GMT+8, 2024-11-22 23:45 , Processed in 0.016716 second(s), 22 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部