参考云游道士: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": "u5c0fu660e", "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'x80x03}qx00(Xx02x00x00x00k1qx01Xx02x00x00x00v1qx02Xx02x00x00x00k2qx03Xx02x00x00x00v2qx04u.' 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'}