序列化和反序列化

为什么要序列化
内存中的字典、列表、集合以及各种对象,如何保存到一个文件中?
如果是自己定义的类的实例,如何保存到一个文件中?
如何从文件中读取数据,并让它们在内存中再次恢复成对应的类的实例?
要设计一套协议,按照某种规则,把内存中数据保存到文件中。文件是一个字节序列,所以必须把数据转换成字节序列,输出到文件。这就是序列化。反之,从文件的字节序列恢复到内存并且还是原来的类型,这就是反序列化。
定义

  • serialization序列化:将内存中对象存储下来,把它编程一个个字节。->二进制
  • deserialization反序列化:将文件的一个个字节恢复成内存中对象。<-二进制
  • 序列化保存到文件就是持久化:可以将数列序列化后持久化,或者网络传输,也可以将从文件中或者网络接受到的字节序列反序列化
  • python提供了pickle库
    pickle库
    python中序列化、反序列化模块

函数

说明

dumps

对象序列化为bytes对象

dump

对象序列化到文件对象那个,就是存入文件

loads

从bytes对象反序列化

load

对象反序列化,从文件读取数据

  • 序列化
序列化
import pickle
a=99
b='c'
c=[48,'abc']
d={'a':'ddd','b':1}
with open('e:/c.txt','wb+') as f:
    pickle.dump(a,f)
    pickle.dump(b,f)
    pickle.dump(c,f)
    pickle.dump(d,f)

Python对象序列化与反序列化的魔法方法 python中序列化和反序列化_json


Python对象序列化与反序列化的魔法方法 python中序列化和反序列化_json_02


序列化后得到的是一个二进制序列,二进制序列中有很多不认识的,表示的是原来存储前数据的类型和界定符用的方法是dumps。

这里使用dump是存入文件中

  • 反序列化
#反序列化
with open('e:/c.txt','rb+') as t:
    for i in range(4):
        i=pickle.load(t)
        print(type(i),i)

Python对象序列化与反序列化的魔法方法 python中序列化和反序列化_序列化_03


使用load将文件中的队行反序列化,需要读取界定符,原来的数据类型。

loads是将bytes对象反序列化

还原回的已经不是原来的

  • 对象序列化
#对象序列化
class AAA:
    t='abc' 
    def show(s):
        print('abc')
a=AAA()
#序列化
ser=pickle.dumps(a)
print(ser)
#反序列化
a1=pickle.loads(ser)
print(a1.t)
a1.show()

Python对象序列化与反序列化的魔法方法 python中序列化和反序列化_json_04


序列化只序列化了AAA类,反序列化回根据目前的类补全函数。

  • 序列化应用
    一般的说,本地序列化的情况应用较少。大多数场景都是应用在网络传输中。
    将数据序列化后通过网络传输到远程结点,远程服务器上的服务将接收到的数据反序列化后,就可以使用了,但是要注意一点,源程接收端,反序列化时必须要有对应的数据类型,否则会报错。尤其是自定义类,必须远程得有一致的定义。
    目前,大多数项目都不是单机的,要不是单服务的,需要多个程序之间配合,需要通过网络将数据传送到其他结点上去,这就需要大量的序列化、反序列化过程
Json

JSON(javaScript Object Notation,JS 对象标记)是一种轻量级的数据交换格式,它基于ECMAScript(w3w组织制定的JS规范)的一个子集,采用完全独立于编程语言的文本格式啦储存和表示数据
http://json.org/Json的数据类型


  • 双引号引起来的字符串,数值,true和false,null,对象,数组,这些都是值
    value

    字符串:由双引号包围起来的任意字符的组合,可以有转移字符
    数值:有正负、有整数、浮点数。
    对象:无序的键值对的集合,格式:{key1:value1,……,keyn:valuen},key必须是一个字符串,需要双引号包围这个字符串,value可以是任意合法的值

    数组:有序的值的集合,格式[val1,……,valn]
Json模块

Python与Json
Python支持少量内建数据类型到Json类型的转换

Python

Json类型

True

true

False

false

None

str

string

int

integer

float

float

list

array

dict

object

python中set集不能识别
常用方法

Python类型

Json类型

dumps

Json编码

dump

Json编码并存入文件

loads

Json解码

load

Json解码,从文件读取数据

import json
d={'name':'Tom','age':20,'interest':('music','movie'),'class':['python']}
j=json.dumps(d)
print(j,type(j))
d1=json.loads(j)
print(d1,type(d1))
print(id(d),id(d1))

Python对象序列化与反序列化的魔法方法 python中序列化和反序列化_json_05

  • 可以看出pickle序列化占的字符多,json占的字符少,在python中使用pickle什么类型都可以传输,json不能识别python中的set集

一般Json便阿门的数据很少落地,数据都是通过网络传输,传输的时候,要考虑压缩它
本质上来说它就是个文本,就是个字符串
json很简单,几乎编程语言都支持json,所以引用范围十分广泛

MessagePack

MessagePack是一个基于二进制高效的对象序列化类库,可用于跨语言通信。
它可以像Json那样,在许多种语言之间交换结构对象
但是它比Json更快速也更轻巧
支持Python、Ruby、Java等众多语言,兼容Json和pickle

  • python安装
  • 常用方法
    dumps,转换成二进制序列,序列化
    dump,转换成二进制序列后存入文件,序列化
    loads,将二进制序列转化为原来模式,反序列化
    load,将文件转换成原来模式,反序列化
  • 三种序列化的对比
#pickle、json、msgpack序列化对比
import json
import pickle
import msgpack
d={'name':'Tom','age':20,'interest':('music','movie'),'class':['python']}
#json序列化
j=json.dumps(d)
print(j,type(j),len(j))
#pickle序列化
p=pickle.dumps(d)
print(p,type(p),len(p))
#msgpack序列化
m=msgpack.dumps(d)
print(m,type(m),len(m))

Python对象序列化与反序列化的魔法方法 python中序列化和反序列化_序列化_06


MessagePack简单易用,高效压缩,支持语言丰富

所以,用它序列化也是一种很好的选择。