Python编程:序列化和反序列化

前言

前面在学习时,简单介绍了Python中的序列化和反序列化。我们已经知道,在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict:,我们可以随时修改变量的值,比如把改成。但是一旦程序结束,变量所占用的内存就被操作系统全部回收。如果没有把修改后的存储到磁盘上,下次重新运行程序,变量又被初始化为。

今天我们就来系统地学习Python中的序列化和反序列化。

序列化和反序列化

在python中,序列化可以理解为:把python的对象编码转换为json格式的字符串,反序列化可以理解为:把json格式字符串解码为python数据对象。

我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

在python的标准库中,专门提供了json库与pickle库来处理这部分。

pickle模块

使用pickle模块,首先要导入该模块:

把序列化后的内容存储在变量中

返回结果是序列化后的字节数据。

运行结果:

把序列化后的数据还原为对象(反序列化)

经过上面的序列化后,数据以字节保存在了变量中,需要再次使用的时候使用函数就行了。如下:

运行结果:

直接存储在文件中

上面的方法把任意对象序列化成一个,然后,就可以把这个写入文件。或者用另一个方法直接把对象序列化后写入一个,进行持久化。注意这次用的方法中少了个,即:,而不是上面用到的。

由于pickle写入的是二进制数据,所以打开方式需要以和的模式。

运行结果:

直接把序列化后的内容写入到文件中

也可以直接用方法从一个中直接反序列化出对象。如下:

运行结果:

这样我们的数据就从文件中成功地反序列化到内存,保存到变量中了。要注意的是:这个变量和原来的变量是完全不相干的对象,它们只是内容相同而已。

序列化用户自定义对象

开发中用的最多的就是我们自己定义类的对象,pickle当然也能写入,不仅可以写入类本身,也能写入它的一个实例。

假设我们现在设计了一个类:

将类本身序列化到文件中:

运行结果:

将类本身序列化到文件中

将自定义类从文件中反序列化出来,并创建对象:

运行结果:

接下来,看下如何序列化自定义类的对象:

运行结果:(2处影响):

1.创建了文件,并写入了序列化后的数据到该文件中。

创建了文件,并写入了序列化后的数据

2.打印结果:

从文件中反序列化出对象:

运行结果:

上面演示了pickle模块序列化和反序列化,两套方法:序列化到文件并反序列化到变量的和序列化到文件并反序列化的。

json模块

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

提示:本质就是字符串,是一个特殊格式的字符串而已。

JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

Python内置的json模块提供了非常完善的Python对象到JSON格式的转换。我们先看看如何把Python对象变成一个JSON:

如果您有一个对象x,则可以使用一行简单的代码查看其JSON字符串表示:

运行结果:

提示:

1.使用前要先导入模块,此处是方法,区别于方法。如果你遇到了下面错误,请检查方法是否使用错误:

此文中用的python是3.5,在版本3.6中已更改:所有可选参数现在仅为关键字。

2.方法的另一个变体,只是将对象序列化为文本文件。

dumps()方法返回一个str,内容就是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like Object。

要把JSON反序列化为Python对象,用或者对应的方法,前者把JSON的字符串反序列化,后者从中读取字符串并反序列化。

用反序列化

运行结果:

用反序列化

用反序列化,直接将文件反序列化为内存中的对象。

运行结果:

JSON进阶

Python的等对象可以直接序列化为JSON的,不过,很多时候,我们更喜欢用表示对象,比如定义类,然后序列化:

运行结果:

解析:发现报错了,错误的原因是对象不是一个可序列化为的对象。

查看该方法官方文档,此文中用的python是3.5,在版本3.6中已更改:所有可选参数现在仅为关键字。

这些参数就是让我们来定制JSON序列化。前面的代码之所以无法把类实例序列化为,是因为默认情况下,方法不知道如何将实例变为一个的对象。

可选参数就是把任意一个对象变成一个可序列为的对象,我们只需要为专门写一个转换函数,再把函数传进去即可:

我们再进行序列化时,就可以用到该函数了:

运行结果:

不过,下次如果遇到一个类的实例,照样无法序列化为JSON。我们可以偷个懒,把任意class的实例变为dict,我们可以这么干:

之所以可以这么写,是因为通常的实例都有一个属性,它就是一个,用来存储实例变量。要特别注意,也有少数例外,比如定义了的。

同样的道理,如果我们要把反序列化为一个对象实例,方法首先转换出一个对象,然后,我们传入的函数负责把转换为实例:

核心代码:

运行结果:

打印出的是反序列化的实例对象:

以上是存储到变量,存储到文件也是类似操作。

小结

本小节系统地学习了python中如何序列化和反序列化。重点学习python的标准库中的专门提供的:。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180716G065BC00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券