序列化与反序列化的应用
Posted lw-whatever
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了序列化与反序列化的应用相关的知识,希望对你有一定的参考价值。
在python中,我们需要将内置的数据结构如元组、列表、字典处理为str类型,这个时候就需要进行序列化处理;如果进行反序列化处理,数据类型则仍然是列表、字典,但是元组经过反序列化后,数据类型会转为列表。进行序列化和反序列化,我们需要用到json库。在这个库中,序列化和反序列化处理分为两部分,一部分是直接对数据类型进行处理,另一部分是对文件内容的处理。
1 import json 2 3 4 tuple1 = (1, 2, 3) 5 print(‘未处理之前的数据类型:‘, type(tuple1)) 6 7 #对元组进行序列化处理 8 tuple1_str = json.dumps(tuple1) 9 print(‘经过序列化处理之后的数据类型:‘, type(tuple1_str), tuple1_str) 10 11 #对字符串tuple1_str进行反序列化处理 12 str_tuple1 = json.loads(tuple1_str) 13 print(‘经过反序列化处理之后的数据类型:‘, type(str_tuple1), str_tuple1)
运行后得到结果:
未处理之前的数据类型: <class ‘tuple‘> 经过序列化处理之后的数据类型: <class ‘str‘> [1, 2, 3] 经过反序列化处理之后的数据类型: <class ‘list‘> [1, 2, 3]
从输出结果中,我们可以看到元组在经过序列化处理后,数据类型变成了str类型,在经过反序列化之后,数据类型并没有变回元组,而是列表。
1 list1 = [1, 2, 3] 2 print(‘未处理之前的数据类型:‘, type(list1)) 3 4 #对列表进行序列化处理 5 list1_str = json.dumps(list1) 6 print(‘经过序列化处理之后的数据类型:‘, type(list1_str), list1_str) 7 8 #对字符串list1_str进行反序列化处理 9 str_list1 = json.loads(list1_str) 10 print(‘经过反序列化处理之后的数据类型:‘, type(str_list1), str_list1)
运行后得到结果:
未处理之前的数据类型: <class ‘list‘> 经过序列化处理之后的数据类型: <class ‘str‘> [1, 2, 3] 经过反序列化处理之后的数据类型: <class ‘list‘> [1, 2, 3]
我们可以看到,列表在经过序列化处理后,数据类型变成了str 类型;经过反序列化之后,数据类型又变回了list。
1 dict1 = {‘id‘: 1, ‘name‘: ‘张三‘} 2 print(‘未处理之前的数据类型:‘, type(dict1)) 3 4 #对字典进行序列化处理 5 dict1_str = json.dumps(dict1) 6 print(‘经过序列化处理之后的数据类型:‘, type(dict1_str), dict1_str) 7 8 #对字符串dict1_str进行反序列化处理 9 str_dict1 = json.loads(dict1_str) 10 print(‘经过反序列化处理之后的数据类型:‘, type(str_dict1), str_dict1)
运行后得到结果:
未处理之前的数据类型: <class ‘dict‘> 经过序列化处理之后的数据类型: <class ‘str‘> {"id": 1, "name": "u5f20u4e09"} 经过反序列化处理之后的数据类型: <class ‘dict‘> {‘id‘: 1, ‘name‘: ‘张三‘}
字典在经过序列化后也是变成了str的数据类型,反序列化后又重新变回了字典的数据类型
1 import os 2 3 4 data_dir = os.path.join(os.path.dirname(__file__), ‘data‘, ‘api.json‘) 5 6 dict1 = {‘name‘: ‘张三‘} 7 with open(data_dir, ‘w‘) as fp: 8 fp.write(dict1)
运行后得到结果:
Traceback (most recent call last): File "/Users/yezhenxiang/PycharmProjects/Test/lagou.py", line 13, in <module> fp.write(dict1) TypeError: write() argument must be str, not dict
上面的例子想要实现的目的是将dict1写入到文件api.json中,但是我们按照正常的方式写入时,最终报错了,这是因为dict1的数据类型时字典,程序无法直接将字典写入。这个时候,就要使用到文件的序列化了
先来看下dump方法的源码:
1 def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, 2 allow_nan=True, cls=None, indent=None, separators=None, 3 default=None, sort_keys=False, **kw):
从上面的源码中,需要关注的是dump方法中第一个和第二个参数,分别是文件的对象和打开的文件句柄,了解了dump的原理后,就可以使用dump来进行序列化写入文件了,来看下面的例子:
1 import json 2 import os 3 4 5 data_dir = os.path.join(os.path.dirname(__file__), ‘data‘, ‘api.json‘) 6 7 dict1 = {‘name‘: ‘张三‘} 8 json.dump(dict1, open(data_dir, ‘w‘))
运行程序后,dict1成功写入api.json文件中
{"name": "u5f20u4e09"}
文件的序列化我们使用dump,这样就可以将不是string类型的数据类型写入到文件中了。但是在输出的结果中,写入到文件是bytes类型,如果我们想要将自己看的懂的文件写入,可以使用ensure_ascii=False,如下:
1 json.dump(dict1, open(data_dir, ‘w‘, encoding=‘utf-8‘), ensure_ascii=False)
1 import json 2 import os 3 4 5 6 data_dir = os.path.join(os.path.dirname(__file__), ‘data‘, ‘api.json‘) 7 8 dict1 = {‘name‘: ‘张三‘} 9 #对文件进行序列化写入 10 json.dump(dict1, open(data_dir, ‘w‘, encoding=‘utf-8‘), ensure_ascii=False) 11 12 #对保存的文件进行读取 13 file_dict = open(data_dir) 14 content = file_dict.read() 15 print(type(content), content)
运行后得到结果:
<class ‘str‘> {"name": "张三"}
可以从读读取的内容中看出,文件中保存的数据是str类型的,这样显然不利于我们对文件内容的处理,所以如果在需要处理文件内容的时候,我们就需要根据情况进行反序列化将文件中的内容读取出来
反序列化的方法如下:
1 import json 2 import os 3 4 5 6 data_dir = os.path.join(os.path.dirname(__file__), ‘data‘, ‘api.json‘) 7 8 dict1 = {‘name‘: ‘张三‘} 9 json.dump(dict1, open(data_dir, ‘w‘, encoding=‘utf-8‘), ensure_ascii=False) 10 11 #对文件进行反序列化 12 dict1 = json.load(open(data_dir, ‘r‘)) 13 print(dict1, type(dict1))
运行后得到结果:
{‘name‘: ‘张三‘} <class ‘dict‘>
在最后的打印中可以看到文件的类型是字典类型,我们就可以用处理字典的方式来有效的操作文件中的内容了。
以上是关于序列化与反序列化的应用的主要内容,如果未能解决你的问题,请参考以下文章