Python的数据序列化「Json & Pickle」
[attach]1460[/attach]在介绍Python的数据序列化模块「Json & Pickle」之前,我们先来看看为什么需要数据序列化,什么是数据序列化。
为什么需要数据序列化,我认为有如下两种原因:
一个原因是将对象(一切皆对象)的状态保持在存储媒介(硬盘、网盘......)中,以便可以在以后重新创建精确的副本,相当于镜像的概念,比如我们平时利用VMware虚拟机中的挂起功能,这个挂起功能就是利用数据的序列化,把虚拟机当前的状态序列化保存在本地磁盘的文件中,然后恢复的时候只需反序列化,把状态恢复即可。
另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。例如,你利用Python监控采集程序采集到的数据想传送给Zabbix处理。当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。
序列化和反序列化:
dumps把数据类型转换成字符串 dump把数据类型转换成字符串并存储在文件中 loads把字符串转换成数据类型 load把文件打开从字符串转换成数据类型 实例如下:dumps把数据类型转换成字符串 dump把数据类型转换成字符串并存储在文件中 loads把字符串转换成数据类型 load把文件打开从字符串转换成数据类型
Pickle可以序列化一些较复杂的数据,和json的区别在于pickle序列化的时候,存放的是二进制的文件,所以打开一个文件的时候,我们要以二进制的格式打开。
实例如下:
- 序列化: 将数据结构或对象转换成二进制串的过程。
- 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。
Json:用于字符串和 python数据类型间进行转换;Json模块提供了四个功能:dumps、dump、loads、load[list=1]Json Module
#!/usr/bin/env python3# _*_coding:utf-8_*_# Author: Lucky.chenimport jsoninfo = {'1MinLoad': 5, 'MemUse': '5G', 'DiskUse': '80G'}print('dumps 操作之前数据类型: %s' % type(info))JsonInfo = json.dumps(info)print(JsonInfo)# dumps 将数据通过特殊的形式转换为所有程序语言都识别的字符串print('dumps 操作之后数据类型: %s' % type(JsonInfo))# loads 将字符串通过特殊的形式转为python是数据类型 (将字符串转为字典)NewInfo = json.loads(JsonInfo)print('loads 操作之后数据类型为: %s' % type(NewInfo))print('分割线'.center(50, '-'))# dump 将数据通过特殊的形式转换为所有语言都识别的字符串并写入文件with open('SystemInfo.txt', 'w') as f: json.dump(info, f) print('dump file end!!')# load 从文件读取字符串并转换为python的数据类型with open('SystemInfo.txt', 'r') as f: LoadInfo = json.load(f) print('load file end, data type is %s' % type(LoadInfo), LoadInfo)结果如下:
dumps 操作之前数据类型:一个错误案例如下:{"MemUse": "5G", "DiskUse": "80G", "1MinLoad": 5}dumps 操作之后数据类型: loads 操作之后数据类型为: -----------------------分割线------------------------dump file end!!load file end, data type is {'MemUse': '5G', '1MinLoad': 5, 'DiskUse': '80G'}
#!/usr/bin/env python3# _*_coding:utf-8_*_# Author: Lucky.chenimport jsondef test(): print('Test Func')info = {'Name': 'crh', 'age': 18, 'Func': test}json.dumps(info)结果:
raise TypeError(repr(o) + " is not JSON serializable")TypeError:如上可知函数不能被json序列化。is not JSON serializable
pickle,用于python特有的类型 和 python的数据类型间进行转换Pickle模块同样提供了四个功能:dumps、dump、loads、load[list=1]Pickle Module
#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Author: Lucky.chen
import pickle
def test(name):
print('%s write Test Func' % name)
info = {'Name': 'crh', 'age': 18, 'Func': test}
print('dumps 之前数据的类型为: %s' % type(info))
# pickle.dumps 将数据通过特殊的形式转换为只有python语言认识bytes类型(Python2.*中是字符串类型)
NewInfo = pickle.dumps(info)
print('dumps result is %s, data type is %s' % (NewInfo, type(NewInfo)))
# pickle.loads 将bytes通过特殊的形式转为python是数据类型
LoadInfo = pickle.loads(NewInfo)
print('loads result is %s, data type is %s' % (LoadInfo, type(LoadInfo)))
LoadInfo['Func']('crh')
print('分割线'.center(50, '-'))
# pickle.dump 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
with open('pickle.rb', 'wb') as f:
pickle.dump(info, f)
# pickle.load 从文件读取只有python语言认识的字符串并转换为python的数据类型
with open('pickle.rb', 'rb') as f:
Info = pickle.load(f)
print(Info, 'type is %s' % type(Info))
结果如下:
dumps 之前数据的类型为:dumps result is b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x12X\x04\x00\x00\x00Nameq\x02X\x03\x00\x00\x00crhq\x03X\x04\x00\x00\x00Funcq\x04c__main__\ntest\nq\x05u.', data type is loads result is {'age': 18, 'Name': 'crh', 'Func': }, data type is crh write Test Func -----------------------分割线------------------------ {'age': 18, 'Name': 'crh', 'Func': } type is
很多情况下不同的程序之间传送数据我们一般通过文件的方式,但是这个方法是最原始的,而dumps可以直接让数据格式化传送给对方,但是不是所有的程序都是python的,所以只利用pickle是不现实的,比如一个python的程序需要发送一段数据给一个java程序开发的应用,这时候很多内存数据的交换,就得用json了。 并且josn能dump的结果更可读,那么有人就问了,那还用pickle做什么不直接用josn,是这样的josn只能把常用的数据类型序列化(列表、字典、列表、字符串、数字、),比如日期格式、类对象!josn就不行了。 为什么他不能序列化上面的东西呢?因为josn是跨语言的!注定了它只能规范出一些通用的数据类型的格式,统一标准。总结