序列化的概念很简单。内存里面有一个数据结构,你希望将它保存下来,重用,或者发送给其他人。
pickle
模块是Python标准库的一部分, 所以它总是可用的。它很快; 它的大部分同Python解释器本身一样是用C写的。 它可以存储任意复杂的Python数据结构。
pickle 协议是Python特定的,没有任何跨语言兼容的保证。你很可能不能使用Perl, php, Java, 或者其他语言来对你刚刚创建的entry.pickle
文件做任何有用的事情。
最新版本的pickle协议是二进制格式的。请确认使用二进制模式来打开pickle文件,否则当你写入的时候数据会被损坏。
1.保存数据到 Pickle 文件
2.序列化到一个内存中的bytes
对象
3.调试Pickle 文件
pickletools.dis(f)
Python 3 在标准库中包含了一个 json
模块。同 pickle
模块类似, json
模块包含一些函数,可以序列化数据结构,保存序列化后的数据至磁盘,从磁盘上读取序列化后的数据,将数据反序列化成新的Pythone对象
首先, json数据格式是基于文本的, 不是二进制的。
由于是文本格式, 存在空白(whitespaces)的问题。 json 允许在值之间有任意数目的空白(空格, 跳格, 回车,换行)。
1.将数据保存至 json 文件
with open('basic.json', mode='w', encoding='utf-8')as f:
json 是一个基于文本的格式, 这意味你可以以文本模式打开文件,并给定一个字符编码。用utf-8总是没错的。
2.序列化json不支持的数据类型
即使json没有内建的字节流支持, 并不意味着你不能序列化bytes
对象。json
模块提供了编解码未知数据类型的扩展接口。(“未知”的意思是≴json没有定义”。很显然json
模块认识字节数组, 但是它被json规范的限制束缚住了。) 如果你希望编码字节串或者其它json没有原生支持的数据类型,你需要给这些类型提供定制的编码和解码器。
可以定义自己的“迷你序列化格式。”
1 def to_json(python_object): 2 if isinstance(python_object, bytes): 3 return {'__class__': 'bytes', 4 '__value__': list(python_object)} 5 raise TypeError(repr(python_object) + ' is not JSON serializable')
json.dump(entry, f,defaultcustomserializer.to_json)
3.从json文件加载数据
json.load()
并不知道你可能传给json.dump()
的任何转换函数的任何信息。你需要的是to_json()
函数的逆函数 — 一个接受定制转换出的json 对象并将其转换回原始的Python数据类型。
1 def from_json(json_object): 2 if '__class__' in json_object: 3 if json_object['__class__'] == 'time.asctime': 4 return time.strptime(json_object['__value__']) 5 if json_object['__class__'] == 'bytes': 6 return bytes(json_object['__value__']) 7 return json_object 8 9 with open('entry.json', 'r', encoding='utf-8') as f: 10 entry = json.load(f,object_hook=from_json)
json 并不区分元组和列表;它只有一个类似列表的数据类型,数组,并且json
模块在序列化过程中会安静的将元组和列表两个都转换成json 数组。大多数情况下,你可以忽略元组和列表的区别,但是在使用json
模块时应记得有这么一回事
很多关于pickle
模块的文章提到了cPickle
。在Python 2中, pickle
模块有两个实现, 一个由纯Python写的而另一个用C写的(但仍然可以在Python中调用)。在Python 3中, 这两个模块已经合并, 所以你总是简单的import pickle
就可以。