参考云游道士:https://www.cnblogs.com/yyds/p/6563608.html
1.什么是序列化
序列化就是将字典,数字等数据类型转换为字符串数据类型
所说的序列就是字符串
2.为什么要序列化
1.把内存中的各种数据类型的数据通过网络传送给其它机器或客户端;
2.把内存中的各种数据类型的数据保存到本地磁盘持久化;
相关模块
json 用于实现Python数据类型与通用(json)字符串之间的转换,只有一部分数据类型可用json转换,数字,字符串,列表,字典,元祖
常用方法:dumps()、dump()、loads()、load()
pickle 用于实现Python数据类型与Python特定二进制格式之间的转换,所有数据类型都可以实现转换
常用方法:dumps()、dump()、loads()、load()
shelve 专门用于将Python数据类型的数据持久化到磁盘,shelve是一个类似dict的对象,操作十分便捷.
常用方法:open()
3.JSON序列化/反序列化实例:
序列化
# 序列化
import json
ret = json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)})
print(ret)
{"a": "str", "c": true, "e": 10, "b": 11.1, "d": null, "f": [1, 2, 3], "g": [4, 5, 6]}
sort_keys参数: 表示序列化时是否对dict的key进行排序(dict默认是无序的)
import json
ret = json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)},sort_keys=True)
print(ret)
{"a": "str", "b": 11.1, "c": true, "d": null, "e": 10, "f": [1, 2, 3], "g": [4, 5, 6]}
indent参数: 表示缩进的意思,它可以使得数据存储的格式变得更加优雅、可读性更强;如果indent是一个非负整数或字符串,则JSON array元素和object成员将会被以相应的缩进级别进行打印输出;
如果indent是0或负数或空字符串,则将只会插入换行,不会有缩进。
import json
ret = json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)},sort_keys=True,indent=4)
print(ret)
{
"a": "str",
"b": 11.1,
"c": true,
"d": null,
"e": 10,
"f": [
1,
2,
3
],
"g": [
4,
5,
6
]
}
separators参数: 尽管indent参数可以使得数据存储的格式变得更加优雅、可读性更强,但是那是通过添加一些冗余的空白字符进行填充的。
当json被用于网络数据通信时,应该尽可能的减少无用的数据传输,这样可以节省带宽并加快数据传输速度。
json模块序列化Python对象后得到的json字符串中的','号和':'号分隔符后默认都会附加一个空白字符,我们可以通过separators参数重新指定分隔符,从而去除无用的空白字符;
- 该参数的值应该是一个tuple(item_separator, key_separator)
- 如果indent是None,其默认值为(', ', ': ')
- 如果indent不为None,则默认值为(',', ': ')
- 我们可以通过为separator赋值为(',', ':')来消除空白字符
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)})
'{"a": "str", "c": true, "b": 11.1, "e": 10, "d": null, "g": [4, 5, 6], "f": [1, 2, 3]}' >>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, separators=(',',':'))
'{"a":"str","c":true,"b":11.1,"e":10,"d":null,"g":[4,5,6],"f":[1,2,3]}'
ensure_ascii参数: 当该参数的值为True(默认值)时,输出中的所有非ASCII字符(比如中文)都会被转义成'\uXXXX'组成的序列,得到的结果是一个完全由ASCII字符组成的str实例。
如果我们想得到一个人类可读的输出结果,需要把ensure_ascii参数的值设置为False。
import json
ret1 = json.dumps( {'name':'小明','age':16})
print(ret1)
{"name": "\u5c0f\u660e", "age": 16}
ret2 = json.dumps( {'name':'小明','age':16},ensure_ascii=False)
print(ret2)
{"name": "小明", "age": 16}
反序列化
import json
ret1 = json.dumps( {'name':'小明','age':16},ensure_ascii=False)
print(ret1)
{"name": "小明", "age": 16}
ret2 = json.loads(ret1)
print(ret2)
{'name': '小明', 'age': 16}
json的dump()与load()函数示例
dump 和load 是针对文件进行操作的
dic = {'a':1,'b':2,'c':3}
with open('file',mode='w',encoding='utf-8') as f:
json.dump(dic,f)
### json dump 会先将数据进行序列化,然后再写入文件中
### json load 则会将数据再文件读出来,序列化
with open('file', mode='r', encoding='utf-8') as f:
res = json.load(f)
print(type(res),res)
4.pickle模块
pickle模块实现了用于对Python对象结构进行 序列化 和 反序列化 的二进制协议,与json不同的是,pickle限定于python使用
pickle是二进制协议,读写也得基于二进制方式进行
import pickle
dic = {'k1':'v1','k2':'v2'}
str_dic = pickle.dumps(dic)
print(str_dic) #一串二进制内容
# b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04u.'
dic2 = pickle.loads(str_dic)
print(dic2) #字典
# {'k1': 'v1', 'k2': 'v2'} import time
struct_time1 = time.localtime(1000000000)
struct_time2 = time.localtime(2000000000)
f = open('pickle_file','wb')
pickle.dump(struct_time1,f)
pickle.dump(struct_time2,f)
f.close()
# pickle的 dump 和 load 功能与json类似,都是基于文件操作的
f = open('pickle_file','rb')
struct_time1 = pickle.load(f)
struct_time2 = pickle.load(f)
print(struct_time1.tm_year)
print(struct_time2.tm_year)
f.close()
5.selve模块
shelve是一个简单的数据存储方案,类似key-value数据库,可以很方便的保存python对象,其内部是通过pickle协议来实现数据序列化。
shelve只有一个open()函数,这个函数用于打开指定的文件(一个持久的字典),然后返回一个shelf对象。shelf是一种持久的、类似字典的对象。
它与“dbm”的不同之处在于,其values值可以是任意基本Python对象--pickle模块可以处理的任何数据。这包括大多数类实例、递归数据类型和包含很多共享子对象的对象。keys还是普通的字符串。
import shelve
# 保存数据
with shelve.open('student') as db:
db['name'] = 'Tom'
db['age'] = 19
db['hobby'] = ['篮球', '看电影', '弹吉他']
db['other_info'] = {'sno': 1, 'addr': 'xxxx'} # 读取数据
with shelve.open('student') as db:
for key,value in db.items():
print(key, ': ', value) name : Tom
age : 19
hobby : ['篮球', '看电影', '弹吉他']
other_info : {'sno': 1, 'addr': 'xxxx'}