序列化 Python 对象

问题

你需要将一个 Python 对象序列化为一个字节流,以便将它保存到一个文件、存储到数据库或者通过网络传输它。

解法

对于序列化最普遍的做法就是使用 pickle 模块。为了将一个对象保存到一个文件中,可以这样做:

import pickledata = ... # Some Python object
f = open('somefile', 'wb')
pickle.dump(data, f)

为了将一个对象转储为一个字符串,可以使用 pickle.dumps() :

s = pickle.dumps(data)

为了从字节流中恢复一个对象,使用 picle.load() 或 pickle.loads() 函数。比如:

# Restore from a file
f = open('somefile', 'rb')
data = pickle.load(f)# Restore from a string
data = pickle.loads(s)

讨论

对于大多数应用程序来讲, dump() 和 load() 函数的使用就是你有效使用 pickle模块所需的全部了。它可适用于绝大部分 Python 数据类型和用户自定义类的对象实例。如果你碰到某个库可以让你在数据库中保存/恢复 Python 对象或者是通过网络传输对象的话,那么很有可能这个库的底层就使用了 pickle 模块。

pickle 是一种 Python 特有的自描述的数据编码。通过自描述,被序列化后的数据包含每个对象开始和结束以及它的类型信息。因此,你无需担心对象记录的定义,它总是能工作。举个例子,如果要处理多个对象,你可以这样做:

>>> import pickle
>>> f = open('somedata', 'wb')
>>> pickle.dump([1, 2, 3, 4], f)
>>> pickle.dump('hello', f)
>>> pickle.dump({'Apple', 'Pear', 'Banana'}, f)
>>> f.close()
>>> f = open('somedata', 'rb')
>>> pickle.load(f)
[1, 2, 3, 4]
>>> pickle.load(f)
'hello'
>>> pickle.load(f)
{'Apple', 'Pear', 'Banana'}
>>>

你还能序列化函数,类,还有接口,但是结果数据仅仅将它们的名称编码成对应的代码对象。例如:

>>> import math
>>> import pickle
>>> pickle.dumps(math.cos)
b'\x80\x03cmath\ncos\nq\x00.'
>>>

当数据反序列化回来的时候,会先假定所有的源数据时可用的。模块、类和函数会自动按需导入进来。对于 Python 数据被不同机器上的解析器所共享的应用程序而言,数据的保存可能会有问题,因为所有的机器都必须访问同一个源代码。

注意:千万不要对不信任的数据使用 pickle.load()。pickle 在加载时有一个副作用就是它会自动加载相应模块并构造实例对象。但是某个坏人如果知道 pickle 的工作原理,他就可以创建一个恶意的数据导致 Python 执行随意指定的系统命令。因此,一定要保证 pickle 只在相互之间可以认证对方的解析器的内部使用。


有些类型的对象是不能被序列化的。这些通常是那些依赖外部系统状态的对象,比如打开的文件,网络连接,线程,进程,栈帧等等。用户自定义类可以通过提供__getstate__() 和__setstate__() 方法来绕过这些限制。如果定义了这两个方法,pickle.dump() 就会调用__getstate__() 获取序列化的对象。类似的,__setstate__()在反序列化时被调用。为了演示这个工作原理,下面是一个在内部定义了一个线程但仍然可以序列化和反序列化的类:

# countdown.py
import time
import threadingclass Countdown:def __init__(self, n):self.n = nself.thr = threading.Thread(target=self.run)self.thr.daemon = Trueself.thr.start()def run(self):while self.n > 0:print('T-minus', self.n)self.n -= 1time.sleep(5)def __getstate__(self):return self.ndef __setstate__(self, n):self.__init__(n)

试着运行下面的序列化试验代码:

>>> import countdown
>>> c = countdown.Countdown(30)
>>> T-minus 30
T-minus 29
T-minus 28
...>>> # After a few moments
>>> f = open('cstate.p', 'wb')
>>> import pickle
>>> pickle.dump(c, f)
>>> f.close()

然后退出 Python 解析器并重启后再试验下:

>>> f = open('cstate.p', 'rb')
>>> pickle.load(f)
countdown.Countdown object at 0x10069e2d0>
T-minus 19
T-minus 18
...

你可以看到线程又奇迹般的重生了,从你第一次序列化它的地方又恢复过来。


pickle 对于大型的数据结构比如使用 array 或 numpy 模块创建的二进制数组效率并不是一个高效的编码方式。如果你需要移动大量的数组数据,你最好是先在一个文件中将其保存为数组数据块或使用更高级的标准编码方式如 HDF5 (需要第三方库的支持)。

由于 pickle 是 Python 特有的并且附着在源码上,所有如果需要长期存储数据的时候不应该选用它。例如,如果源码变动了,你所有的存储数据可能会被破坏并且变得不可读取。坦白来讲,对于在数据库和存档文件中存储数据时,你最好使用更加标准的数据编码格式如 XML, CSV 或 JSON。这些编码格式更标准,可以被不同的语言

《Python Cookbook 3rd》笔记(5.21):序列化 Python 对象相关推荐

  1. 《Python Cookbook 3rd》笔记(1.4):查找最大或最小的N个元素

    <Python Cookbook 3rd>1.4:查找最大或最小的N个元素 问题 怎样从一个集合中获得最大或者最小的N个元素列表? 解法 heapq 模块有两个函数:nlargest()和 ...

  2. Python Cookbook 3rd Edition Documentation

    Python Cookbook 3rd Edition Documentation 文章目录 第一章:数据结构和算法 1.1 解压序列赋值给多个变量 问题 解决方案 讨论 1.2 解压可迭代对象赋值给 ...

  3. 《Python cookbook》笔记二

    <Python cookbook>笔记二 第二章 字符串和文本 -使用多个界定符分割字符串- 你需要将一个字符串分割为多个字段,但是分隔符 (还有周围的空格) 并不是固定 的. # str ...

  4. Machine Learning with Python Cookbook 学习笔记 第8章

    Chapter 8. Handling Images 前言 本笔记是针对人工智能典型算法的课程中Machine Learning with Python Cookbook的学习笔记 学习的实战代码都放 ...

  5. Machine Learning with Python Cookbook 学习笔记 第9章

    Chapter 9. Dimensionality Reduction Using Feature Extraction 前言 本笔记是针对人工智能典型算法的课程中Machine Learning w ...

  6. Machine Learning with Python Cookbook 学习笔记 第6章

    Chapter 6. Handling Text 本笔记是针对人工智能典型算法的课程中Machine Learning with Python Cookbook的学习笔记 学习的实战代码都放在代码压缩 ...

  7. python cookbook 中文百度云_《Python+Cookbook》第三版中文v3.0.0PDF高清完整版免费下载|百度云盘...

    David Beazley是一位居住在芝加哥的独立软件开发者以及图书作者.他主要的工作在于编程工具,提供定制化的软件开发服务,以及为软件开发者.科学家和工程师教授编程实践课程.他最为人熟知的工作在于P ...

  8. 《Python Cookbook 3rd》笔记汇总

    文章目录 一.数据结构 二.字符串和文本 三.数字.日期和时间 四.迭代器与生成器 五.文件与IO 一.数据结构 标题 关键词 1.1:拆分序列后赋值给多个变量 可迭代对象.拆分赋值 1.2:拆分任意 ...

  9. [python Cookbook]阅读笔记

    @toc] 前记:为了补充一下python语法知识,感谢网友的推荐阅读了pythonCookbook,这本书确实不错,以问题为导向,引导解决思路. 这个博文是从阅读笔记typora中直接复制过来的没有 ...

最新文章

  1. lnmp shell安装脚本
  2. DevOps时代测试应该如何应对?
  3. C# 安装部署,关于自定义操作,不能被执行。
  4. DeepMind大招,以视觉为媒介,做无监督机器翻译,效果极好
  5. [转]12篇学通C#网络编程——第二篇 HTTP应用编程(上)
  6. Python小游戏(贪吃蛇)
  7. shell编程之条件语句(文件测试,test命令,字符串和逻辑测试,if单支语句,if双支语句,if多支语句,case命令,用if写跑步小实验)
  8. Linux -su、sudo、限制root远程登录
  9. hard-negative mining 及伪代码实现
  10. Navicat8.0注册码
  11. python矩阵连乘_动态规划:矩阵连乘问题
  12. TB6612FNG电机驱动替代方案
  13. Spurious Local Minima are Common in Two-Layer ReLU Neural Networks
  14. html表单中按钮居中,Ant design StepsForm中如何使底部按钮居中
  15. Spring集成activiti
  16. 桌面图标快捷方式小箭头_如何在Windows 7、8和10中删除(或更改)快捷方式图标上的箭头...
  17. webclient 爬虫bug
  18. CISCO和华为交换机修改密码
  19. 一文读懂直播卡顿优化那些事儿
  20. 详解笔记本电脑开机黑屏如何解决

热门文章

  1. wince中重启网卡
  2. hp服务器如何ghost系统,惠普(HP)电脑安装不了GHOST系统的解决办法
  3. linux怎么设置tomcat自动启动,linux添加tomcat服务并设置开机启动
  4. python特征递归消除
  5. 【转】Ubuntu Desktop下自动启动终端并运行脚本
  6. 【转】DICOM图像像素值(灰度值)转换为CT值
  7. 了解 SharePoint 2010 开发中的关键设计决定
  8. ntnub原理怎么看_老电工由浅入深带你入门学PLC的工作原理和梯形图的编程规则...
  9. php 自动验证类,Thinkphp实现自动验证和自动完成
  10. 【Gym - 101612C】【2017-2018NEERC】Consonant Fencity(状压枚举,预处理)