一切内容都是摘抄,主要是便于回忆和鼓励自己不要间断,更详细内容请见原帖地址:
《深入 python3 》中文版
http://woodpecker.org.cn/diveintopython3/index.html
无关课程的内容,自己研究的部分
可选的有:shelve, pickle, anydbm, JSON
anydbm允许我们将一个磁盘上的文件与一个“dict-like”对象关联起来,操作这个“dict-like”对象,就像操作dict对象一样,最后可以将“dict-like”的数据持久化到文件。对这个"dict-like"对象进行操作的时候,key和value的类型必须是字符串。
shelve模块是anydbm的增强版,它支持在"dict-like"对象中存储任何可以被pickle序列化的对象,但key也必须是字符串。
shelve = pickle + anydbm
13.1. 深入
什么东西能用pickle
模块存储?
- 所有Python支持的 原生类型 : 布尔, 整数, 浮点数, 复数, 字符串,
bytes
(字节串)对象, 字节数组, 以及None
. - 由任何原生类型组成的列表,元组,字典和集合。
- 由任何原生类型组成的列表,元组,字典和集合组成的列表,元组,字典和集合(可以一直嵌套下去,直至Python支持的最大递归层数 ).
- 函数,类,和类的实例(带警告)。
13.1.1. 本章例子的快速笔记
13.2. 保存数据到 Pickle 文件
>>> shell ① 1 >>> import pickle >>> with open('entry.pickle', 'wb') as f: ② ... pickle.dump(entry, f) ③ ...
pickle
模块接受一个Python数据结构并将其保存的一个文件。- 要做到这样,它使用一个被称为“pickle协议”的东西序列化 该数据结构。
- pickle 协议是Python特定的,没有任何跨语言兼容的保证。你很可能不能使用Perl, PHP , Java, 或者其他语言来对你刚刚创建的
entry.pickle
文件做任何有用的事情。 - 并非所有的Python数据结构都可以通过
pickle
模块序列化。随着新的数据类型被加入到Python语言中,pickle协议已经被修改过很多次了,但是它还是有一些限制。 - 由于这些变化,不同版本的Python的兼容性也没有保证。新的版本的Python支持旧的序列化格式,但是旧版本的Python不支持新的格式(因为它们不支持新的数据类型)。
- 除非你指定,
pickle
模块中的函数将使用最新版本的pickle协议。这保证了你对可以被序列化的数据类型有最大的灵活度,但这也意味着生成的文件不能被不支持新版pickle协议的旧版本的Python读取。 - 最新版本的pickle协议是二进制格式的。请确认使用二进制模式来打开你的pickle文件,否则当你写入的时候数据会被损坏。
13.3. 从Pickle文件读取数据
pickle.dump() / pickle.load()循环的结果是一个和原始数据结构等同的新的数据结构。
13.4. 不使用文件来进行序列化
pickle.dumps()
函数(注意函数名最后的's'
)执行和pickle.dump()
函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。- 由于pickle协议使用一个二进制数据格式,所以
pickle.dumps()
函数返回bytes
对象。 pickle.loads()
函数(再一次, 注意函数名最后的's'
) 执行和pickle.load()
函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的bytes
对象, 比如pickle.dumps()
函数返回的对象。
13.5. 字节串和字符串又一次抬起了它们丑陋的头。
13.6. 调试Pickle 文件
import pickletools
13.7. 序列化Python对象以供其它语言读取
pickle
模块使用的数据格式是Python特定的。它没有做任何兼容其它编程语言的努力。如果跨语言兼容是你的需求之一,你得去寻找其它的序列化格式。一个这样的格式是 JSON 。 “JSON ” 代表 “JavaScript Object Notation,” 但是不要让名字糊弄你。 — JSON 是被设计为跨语言使用的。
Python 3 在标准库中包含了一个 json
模块。同 pickle
模块类似, json
模块包含一些函数,可以序列化数据结构,保存序列化后的数据至磁盘,从磁盘上读取序列化后的数据,将数据反序列化成新的Pythone对象。但两者也有一些很重要的区别。 首先, JSON 数据格式是基于文本的, 不是二进制的。RFC 4627 定义了JSON 格式以及怎样将各种类型的数据编码成文本。比如,一个布尔值要么存储为5个字符的字符串'false'
,要么存储为4个字符的字符串 'true'
。 所有的JSON 值都是大小写敏感的。
第二,由于是文本格式, 存在空白(whitespaces)的问题。 JSON 允许在值之间有任意数目的空白(空格, 跳格, 回车,换行)。空白是“无关紧要的”,这意味着JSON 编码器可以按它们的喜好添加任意多或任意少的空白, 而JSON 解码器被要求忽略值之间的任意空白。这允许你“美观的打印(pretty-print)” 你的 JSON 数据, 通过不同的缩进层次嵌套值,这样你就可以在标准浏览器或文本编辑器中阅读它。Python 的 json
模块有在编码时执行美观打印(pretty-printing)的选项。
第三, 字符编码的问题是长期存在的。JSON 用纯文本编码数据, 但是你知道, “不存在纯文本这种东西。” JSON 必须以Unicode 编码(UTF-32, UTF-16, 或者默认的, UTF-8 )方式存储, RFC 4627的第3节 定义了如何区分使用的是哪种编码。
13.8. 将数据保存至 JSON 文件
import json
with open('basic.json', mode='w', encoding='utf-8') as f:
json.dump(basic_entry, f)
json.dump(basic_entry, f, indent=2)
如果你给json.dump()函数传入indent参数, 它以文件变大为代价使生成的JSON文件更可读。indent 参数是一个整数。0 意味着“每个值单独一行。” 大于0的数字意味着“每个值单独一行并且使用这个数目的空格来缩进嵌套的数据结构。”
13.9. 将Python数据类型映射到JSON
注意到什么被遗漏了吗?元组和 & 字节串(bytes)! JSON 有数组类型, json
模块将其映射到Python的列表, 但是它没有一个单独的类型对应 “冻结数组(frozen arrays)” (元组)。而且尽管 JSON 非常好的支持字符串,但是它没有对bytes
对象或字节数组的支持。
13.10. 序列化JSON不支持的数据类型
即使JSON没有内建的字节流支持, 并不意味着你不能序列化bytes对象。json模块提供了编解码未知数据类型的扩展接口。(“未知”的意思是?JSON没有定义”。很显然json 模块认识字节数组, 但是它被JSON规范的限制束缚住了。) 如果你希望编码字节串或者其它JSON没有原生支持的数据类型,你需要给这些类型提供定制的编码和解码器。
以下内容略看,具体情况用到再看教材吧
13.11. 从JSON文件加载数据
但是重现创建的entry2 数据结构中, 'tags' 键的值是一个三个字符串组成的列表。JSON 并不区分元组和列表;它只有一个类似列表的数据类型,数组,并且json模块在序列化过程中会安静的将元组和列表两个都转换成JSON 数组。大多数情况下,你可以忽略元组和列表的区别,但是在使用json 模块时应记得有这么一回使。