这篇文章将为大家详细讲解有关Python中序列化与反序列化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
通俗一点来说,序列化就是将 对象的信息 或者 数据结构的信息 通过一定的规则进行转换,可以达到 文件存储 或 网络传输 的效果。通过前面章节的学习,我们知道如果要进行存储或网络传输,最终的数据类型都是 字符串,而且这些字符串还需要是有一定规则的字符串。
而我们今天要学习的 内置模块 ---> json 可以用于文件存储或者网络传输,这也是序列化的作用。
而反序列化就是通过序列化规则生成的字符串再反转为原始的数据类型,这就是反序列化。
这里我们可以引入 字符串 与 byte 之间的转换来理解 序列化与反序列化, 字符串与 byte 类型之间互相转换常用的 encode() 函数、与 decode() 函数,分别代表着编码与解码,所以有编码,就一定有解码 。套用在序列化来理解,既然存在序列化,那么就肯定有对应的反序列化哈。
哪些数据类型是可以序列化,哪些又是不可以序列化的呢?
可序列化:number、str、list、tuple、dict [字典是最常用的序列化数据类型]
不可序列化:class 、def (函数与实例化对象)、set 是无法进行序列化的
json模块是一个通用的序列化模块,通过它可以完成通用化的序列化与反序列化操作。为什么说是通用的,那是因为几乎所有的编程语言都有json模块,而且他们序列化与反序列化的规则是统一的。
所以我们在 Python 中序列化的内容,在任意其他编程语言中都可以进行反序列化并使用原始的数据,这就是通用的意思。
json 中最重要的函数 - 就是 dumps() 与 loads() 函数
方法名 | 参数 | 介绍 | 举例 | 返回值 |
---|---|---|---|---|
dumps | obj | 对象序列化 | json.dumps([1, 2, 3]) | 字符串 |
loads | str | 反序列化 | Json.loads(’[1, 2, 3]’) | 原始数据类型 |
演示案例如下:
import json int_test = 666 # 定义 整型、字符串、列表、元组、字典 五种数据类型 ,用于序列化测试 str_test = 'test_string' list_test = [1, 2, 3] tuple_test = (4, 5, 6) dict_test = {'Name': '托尼.史塔克', 'Sex': '男'} int_test_json = json.dumps(int_test) # 将上文中五种数据类型进行序列化操作 str_test_json = json.dumps(str_test) list_test_json = json.dumps(list_test) tuple_test_json = json.dumps(tuple_test) dict_test_json = json.dumps(dict_test)
在 Treminal 终端 执行上述测试脚本,如下图:
这里我们重点介绍一下 字典类型的序列化结果
In [7]: dict_test_json Out[7]: '{"Name": "\\u6258\\u5c3c.\\u53f2\\u5854\\u514b", "Sex": "\\u7537"}'
从执行结果我们可以看出字典类型的数据类型,经过序列化后。字典变成了字符串的同时,且字典内的 单引号 变成了 双引号,中文也变成了比特类型,并且进行了 encode 。(这是序列化的一个标准)
为什么我们说 字典类型是非常是和序列化的呢?实际上 json 并不仅仅是一个标准,也是一种文件格式。比如我们编写脚本的 .py 格式的文件,就是 python 文件容器;.txt 格式的文件是普通的文本文件容器;同样的,.json 格式的文件也是文件容器,json 文件存储的样式(格式)就是字典类型的序列化格式。
接下来我们再尝试将上文的五种测试数类型反序列化处理,看看结果会怎样?
_int_test_json = json.loads(int_test_json) _str_test_json = json.loads(str_test_json) _list_test_json = json.loads(list_test_json) _tuple_test_json = json.loads(tuple_test_json) _dict_test_json = json.loads(dict_test_json)
在 Treminal 终端 执行上述测试脚本,如下图:
划重点:元组类型经过序列化处理后再通过反序列化还原数据时,会变为列表数据类型。这是因为 元组类型 是 python 语言中特有的数据类型,json 作为一个通用格式,无法识别元组类型。所以在针对元组类型进行序列化的时候,会先将 元组类型 ,先转为 列表,再进行序列化处理;同样的在进行反序列化处理时,就会将序列化后的 元组类型 ,又转成了 列表类型 。(类型的转换,不影响对数据的使用)
示例如下:
print(json.dumps(True)) # >>> 输出结果:true print(json.dumps(False)) # >>> 输出结果:false print(json.dumps(None)) # >>> 输出结果:null
从上述运行结果来看,bool 类型经过序列化处理后,变成了小写的 true、false;而 None 类型则变成了 小写的 null 。
之所以会这样,是因为在大多数的编程语言中, bool 类型都是小写的 true、false 。json 作为一个通用的序列化模块,也同样遵循着这种规则。(小写的 true、false 依然是字符串类型。 )
接下来我们再将上述的序列化处理后的 bool 、None 类型 进行反序列化处理
print(json.loads(json.dumps(None))) # >>> 输出结果:None print(json.loads(json.dumps(True))) # >>> 输出结果:True print(json.loads(json.dumps(False))) # >>> 输出结果:False
从执行结果我们看到,经过反序列化之后,bool、None 类型又被还原成了 python 可读的状态。
pickle模块与json模块一样可以进行序列化与反序列化,区别在于 pickle 是 Python 内置的序列化模块,而且不像 json 那么通用,它只能用于 python 自身来使用,其他语言可能就无法处理了,但pickle模块的性能是要比 json 更好的。如果是仅仅用于 python 自身来使用,pckle 模块还是一个挺不错的选择哦。
方法名 | 参数 | 介绍 | 举例 | 返回值 |
---|---|---|---|---|
dumps | obj | 对象序列化 | json.dumps([1, 2, 3]) | 比特 |
loads | str | 反序列化 | Json.loads(’[1, 2, 3]’) | 原始数据类型 |
注意:区别于 json ,pickle 模块的 dumps() 函数 返回的是 byte 类型 ,而 loads() 函数也仅支持 byte 类型的 pickle 序列进行反序列化的操作。
pickle模块与json模块的用法是完全一致的,这里我们就不过多的演示,只针对 dict 类型演示一下即可。
需求:
创建一个 test.json 的空文件。
定义一个 write 函数写入 dict 数据类型的内容到 test.json 文件
定义一个 read 函数,将写入到 test.json 文件的内容,反序列化读取出来
# coding:utf-8 import json data = {'name': '托尼·史塔克', 'age': 52, 'top': 185} def read(path): # 定义 read() 函数,读取 test.json 文件(返回对象为 反序列化后的内容) with open(path, 'r') as f: data = f.read() return json.loads(data) def write(path, data): # 定义 write() 函数,将 data 写入到 test.json 文件 with open(path, 'w') as f: if isinstance(data, dict): # 判断 data 是否为字典类型。不是的情况下主动抛出异常 _data = json.dumps(data) f.write(_data) else: raise TypeError('\'data\' 不是一个字典类型的数据') return True if __name__ == '__main__': write('test.json', data) result = read('test.json') print(result) result['Sex'] = 'Man' # 加入 {'Sex': 'Max'} 键值对 write('test.json', result) # 将加入的 键值对 写入 test.json 文件 result_test_json = read('test.json') print(result_test_json)
执行结果如下:
关于“Python中序列化与反序列化的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。