53.json和pickle模块
一、序列化和反序列化
1.1 什么是序列化和反序列化
把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening。
内存中的数据类型-->序列化-->特定的格式(json或者pickle格式)
内存中的数据类型<--反序列化<--特定的格式(json或者pickle格式)
1.2 为什么要序列化
序列化的结果->特定的格式的内容有以下两个用途:
- 可用于存储-->用于存档
- 传输给其他平台使用-->跨平台数据交互
注意:
- 针对用途一的特定格式:可以是一种专用格式->pickle只有Python可以识别
- 针对用途二的特定格式:应给是一种通用的格式,可以被所有的语言识别的格式
1.2 序列化的优点
持久保存状态:内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。但是在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。
跨平台数据交互:序列化时不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。
二. json模块
2.1 json使用方法
Json序列化并不是python独有的,json序列化在java等语言中也会涉及到,因此使用json序列化能够达到跨平台传输数据的目的。
json数据类型和python数据类型对应关系表
Json类型 | Python类型 |
---|---|
{} | dict |
[] | list |
"string" | str |
520.13 | int或float |
true/false | True/False |
null | None |
json模块序列化和反序列化的一个过程如下图所示
import json
import json
struct_data = {'name': 'lwx', 'age': 18, 'sex': 'male'}
print(struct_data, type(struct_data))
data = json.dumps(struct_data)
print(data, type(data))
#{"name": "lwx", "age": 18, "sex": "male"} <class 'str'>
# 注意:无论数据是怎样创建的,只要满足json格式(如果是字典,则字典内元素都是双引号),就可以json.loads出来,不一定非要dumps的数据才能loads
data = json.loads(data)
print(data, type(data))
#{'name': 'lwx', 'age': 18, 'sex': 'male'} <class 'dict'>
# 序列化
with open('Json序列化对象.json', 'w') as fw:
json.dump(struct_data, fw)
print(data)
# {'name': 'lwx', 'age': 18, 'sex': 'male'}
# 反序列化
with open('Json序列化对象.json') as fr:
data = json.load(fr)
print(data)
# {'name': 'lwx', 'age': 18, 'sex': 'male'}
2.2 注意事项
json验证:json格式兼容的是所有语言通用的数据类型,而不是不能识别某一语言独有的数据类型
json.dumps({1,2,3,4,5,6})
# TypeError: Object of type set is not JSON serializable
json强调:一定要弄清楚json格式,不要与python混淆
l=json.loads('[1,"aaa",true,false]')
print(l)
# [1, 'aaa', True, False]
三. pickle模块
Pickle序列化和所有其他编程语言特有的序列化问题一样,它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,即不能成功地反序列化也没关系。但是pickle的好处是可以存储Python中的所有的数据类型,包括对象,而json不可以。
pickle模块序列化和反序列化的过程如下图所示:
import pickle
struct_data = {'name': 'lwx', 'age': 18, 'sex': 'male'}
print(struct_data, type(struct_data))
# {'name': 'lwx', 'age': 18, 'sex': 'male'} <class 'dict'>
data = pickle.dumps(struct_data)
print(data, type(data))
# b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00lwxq\x02X\x03\x00\x00\x00ageq\x03K\x12X\x03\x00\x00\x00sexq\x04X\x04\x00\x00\x00maleq\x05u.'
#<class 'bytes'>
data = pickle.loads(data)
print(data, type(data))
# {'name': 'lwx', 'age': 18, 'sex': 'male'} <class 'dict'>
# 序列化(注意:pickle模块需要使用二进制存储,即'wb'模式存储)
with open('Pickle序列化对象.pkl', 'wb') as fw:
pickle.dump(struct_data, fw)
# 反序列化
with open('Pickle序列化对象.pkl', 'rb') as fr:
pickle = pickle.load(fr)
print(data)