python 序列化和反序列化 (pickle, json)
1. 所谓序列化和反序列化:
(1) 序列化: 把内存中的数据读取出来, 变成可存储或可传输的过程称之为序列化
(2) 反序列化: 把存储好的数据, 转化成原本的数据类型, 叫做反序列化
Note: 程序运行时, 数据都是存储在内存中, 而不是存储在硬盘中(存储在硬盘中的叫做文件), 当程序重新运行时, 数据会被初始化.
2. pickle
pickle 只能在python中使用, 并且不同版本 python 的 pickle 可能彼此不兼容,因此,一般使用 pickle 保存一些不重要的数据,不能成功地反序列化也没关系。
(1) dump, load
dump
(obj, file, protocol=None, *, fix_imports=True)
load
(file, *, fix_imports=True, encoding="ASCII", errors="strict")
import pickle it = iter(range(10)) with open("test.pk", mode="wb") as fp: pickle.dump(it, fp) with open("test.pk", mode="rb") as fp: res = pickle.load(fp)
(2) dumps, loads
dumps
(obj, protocol=None, *, fix_imports=True)
loads
(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")
import pickle ls = [1, 23, 65, 23, 8, 12, 0] #dumps 序列化: 将任意对象序列化成一个 bytes res = pickle.dumps(ls) print(res, type(res)) res = pickle.loads(res) print(res)
3. json (dumps, loads, dump, load)
json 表示的对象是标准的 javascript 语言, 但序列化的数据是字符串, 因此广泛应用于其他的语言.
json 数据类型与 python 数据类型之间的对应如下:
json | python |
object {} | dict |
array [] | list |
string | str |
int/real | int/float/Enums |
true/false | True/False |
null | None |
(1) dump, load
dump
(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
load
(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
dic = {'name': "黄某某", "age": 8, "sex": "男性", "family": ['爸爸', "妈妈"]} with open("test.json", mode="w", encoding="utf-8") as fp: json.dump(dic, fp, ensure_ascii=False) with open("test.json") as fp: res = json.load(fp)
(2) dumps, loads
dumps
(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
loads
(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
import json dic = {'name': "黄某某", "age": 8, "sex": "男性", "family": ['爸爸', "妈妈"]} # 序列化 ''' ensure_ascii=True 如果想要显示中文ensure_ascii = False sort_keys=True 对字典的键进行排序(默认按照 ascii 从小到大排序) ''' res = json.dumps(dic, ensure_ascii=False, sort_keys=True) print(res, type(res)) # 反序列化 res = json.loads(res) print(res, type(res))
4. pickle 和 json 的区别
''' # json 和 pickle 两个模块的区别: (1)json序列化之后的数据类型是str, 所有编程语言都可识别, 但是支持的数据类型有限 json能够连续 dump 不能连续 load, 只能一次性拿出所有数据 (2)pickle序列化之后的数据类型是bytes, 所有数据类型都可转化,但仅限于python之间的存储传输. pickle可以连续load, 多套数据可以放到同一个文件中 ''' # 连续 dump 和 load 示例 ''' json: 可以连续dump,但是load只能一次性把所有数据拿出来进行反序列化,造成数据错误 针对于这个弊端,可以使用loads来解决 ''' dic = {'a': 1, "b": 2} with open("test.json", mode="w", encoding="utf-8") as fp: json.dump(dic, fp) fp.write('\n') json.dump(dic, fp) fp.write('\n') with open("test.json") as fp: # res = json.load(fp) error for i in fp: # 读一行, 反序列化成一个字典,依次循环. res = json.loads(i) print(res, type(res))