什么叫序列化?
序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes
什么叫反序列化?
把字符转成内存数据类型,就叫做反序列化
JSON 函数
使用 JSON 函数需要导入 json 库:import json。
函数 | 描述 |
---|---|
json.dumps | 将 Python 对象编码成 JSON 字符串 |
json.loads | 将已编码的 JSON 字符串解码为 Python 对象 |
为什么要序列化?
你打游戏过程中,打累了,停下来,关掉游戏、想过2天再玩,2天之后,游戏又从你上次停止的地方继续运行,你上次游戏的进度肯定保存在硬盘上了,是以何种形式呢?游戏过程中产生的很多临时数据是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存里,需要存下来?你如何存?把列表变成文件里的多行多列形式?那嵌套字典呢?根本没法存。所以,若是有种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,还是原来的格式的话,那是极好的。
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
只是把数据类型转成字符串到内存的意思?
json.dumps json.loads
1. 把内存的数据,通过网络,共享给远程其他人
2. 定义了不同语言的之前的交互规则
- 纯文件,坏处,不能共享复杂的数据类型
- xml,坏处,占用空间大
- json ,简单, 可读性好,占用空间小
json dumps,loads是针对内存数据转换
In [204]: import json In [205]: dic Out[205]: {'name': 'cmz', 'sex': 'male', 'age': 30} In [206]: s = json.dumps(dic) # 内存的数据转换成字符串 In [207]: s Out[207]: '{"name": "cmz", "sex": "male", "age": 30}' In [208]: type(s) Out[208]: str In [209]: back_s = json.loads(s) # 将内存的数据转换成字典 In [210]: back_s Out[210]: {'name': 'cmz', 'sex': 'male', 'age': 30}
json dump,load是针对文件转换
In [239]: import json In [240]: dic Out[240]: {'name': 'cmz', 'sex': 'male', 'age': 30} In [241]: with open('json.file','w') as fd: # 序列化到文件 .....: json.dump(dic,fd) .....: In [242]: cat json.file {"name": "cmz", "sex": "male", "age": 30} In [243]: with open('json.file','r') as fd: # 反序列化到内存 .....: bak_data = json.load(fd) .....: In [244]: bak_data Out[244]: {'name': 'cmz', 'sex': 'male', 'age': 30} In [245]: type(bak_data) Out[245]: dict
另一种简便方法
In [22]: cmz = '123'
In [23]: json.dump(cmz,open('cmz.json','w')) # 直接存储
In [24]: cat cmz.json
"123"
In [25]: cc = json.load(open('cmz.json','r')) #直接取出
In [26]: cc
Out[26]: '123'
In [27]: type(cc)
Out[27]: str
In [252]: dct='{"1":"111"}' In [253]: print(json.loads(dct)) {'1': '111'} 无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
注意点
In [271]: dic = '{"name":"cmz","age":30}' In [272]: json.loads(dic) Out[272]: {'name': 'cmz', 'age': 30} In [273]: dic = "{'name':'cmz','age':30}" # json不认识单引号 In [274]: json.loads(dic) --------------------------------------------------------------------------- JSONDecodeError Traceback (most recent call last) <ipython-input-274-fe1545dfe2f3> in <module>() ----> 1 json.loads(dic) /usr/lib/python3.5/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) 317 parse_int is None and parse_float is None and 318 parse_constant is None and object_pairs_hook is None and not kw): --> 319 return _default_decoder.decode(s) 320 if cls is None: 321 cls = JSONDecoder /usr/lib/python3.5/json/decoder.py in decode(self, s, _w) 337 338 """ --> 339 obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 340 end = _w(s, end).end() 341 if end != len(s): /usr/lib/python3.5/json/decoder.py in raw_decode(self, s, idx) 353 """ 354 try: --> 355 obj, end = self.scan_once(s, idx) 356 except StopIteration as err: 357 raise JSONDecodeError("Expecting value", s, err.value) from None JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
In [280]: dic = {'name':'cmz','age':30} In [281]: dic_json = json.dumps(dic) In [282]: dic_back = json.loads(dic_json) In [283]: dic_back Out[283]: {'name': 'cmz', 'age': 30} In [284]: dic_json Out[284]: '{"name": "cmz", "age": 30}'
pickle类似
内存转换
In [292]: dic = {'name':'cmz','age':30} In [293]: dic_pickle = pickle.dumps(dic) # 内存中的数据序列化到硬盘 In [294]: dic_pickle Out[294]: b'x80x03}qx00(Xx04x00x00x00nameqx01Xx03x00x00x00cmzqx02Xx03x00x00x00ageqx03Kx1eu.' In [295]: dic_pickle_bak = pickle.loads(dic_pickle) # 反序列化到内存 In [296]: dic_pickle_bak Out[296]: {'name': 'cmz', 'age': 30} In [297]: type(dic_pickle) Out[297]: bytes In [298]: type(dic_pickle_bak) Out[298]: dict
文件
In [306]: dic = {'name':'cmz','age':30} In [307]: with open('pickle.file','wb') as fd: #注意是w是写入str,wb是写入bytes,j是'bytes' .....: pickle.dump(dic,fd) .....: In [309]: cat pickle.file }q(XnameqXcmzqXageqKu. In [311]: with open('pickle.file','rb') as fd: data = pickle.load(fd) .....: In [312]: data Out[312]: {'name': 'cmz', 'age': 30} In [313]: type(data) Out[313]: dict
json vs pickle:
JSON:
优点:跨语言、体积小
缺点:只能支持intstrlist upledict
Pickle:
优点:专为python设计,支持python所有的数据类型
缺点:只能在python中使用,存储数据占空间大