查看原文
其他

浅析Python的序列化与反序列化

爬虫俱乐部 Stata and Python数据分析 2023-01-01

本文作者:谭   可,中南财经政法大学统计与数学学院

本文编辑:郭培军

技术总编:孙一博

Stata&Python云端课程来啦!

      好消息好消息,爬虫俱乐部开辟小鹅通战场!!爬虫俱乐部隆重推出小鹅通网络课程,将Stata基础课程Stata进阶课程Python课程都上传至小鹅通平台,欢迎大家多多支持订阅!报名课程即可加入答疑群,对报名有任何疑问欢迎在公众号后台留言哦。如需了解详情,可以通过课程链接(https://appbqiqpzi66527.h5.xiaoeknow.com/homepage/10)或课程二维码进行访问哦~


引言
序列化就是把数据变成可存储或可传输的过程,只有序列化后的数据才可以写入到磁盘或者通过网络传输到Spark集群的其他节点上;反之,把字节序列恢复为对象的过程称为对象的反序列化。序列化后可以转换为二进制,xml, json等。下面让我们一起来了解下Python中的序列化与反序列化吧!
一、序列化与反序列化

我们把变量从内存中变成可存储或传输的过程称之为序列化,在 Python 中叫 pickling,在其他语言中也被称之为 serialization,flattening 等等。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即 unpickling。对象的序列化主要用途有两个:

1、 把对象的字节序列永久地保存在硬盘上,通常保存在一个文件中。

很多的应用中,需要对一些对象进行序列化,让他们离开内存空间,入住物理硬盘,为了能够长期的保存。例如web服务器的session对象,当10万用户并发访问,就会在内存中出现10万个session对象,内存可能会吃不消。因此可以把session对象序列化到硬盘中,当我们要用它时,再把硬盘中的对象还原到内存中。

2、 在网络上传送对象的字节序列。

当两个进程进行远程通讯时,彼此发送各种类型的数据。无论是哪一种数据,都会以二进制序列的形式在网络上传输。发送方把数据序列化为字节序列,接收方再把字节序列回复为对象形式。实现对象的序列化和反序列化在python中有两种方式:pickle和json。其中pickle用于python特有的类型 和 python的数据类型间进行转换,pickle是python特有的。json用于字符串和 python数据类型间进行转换。
二、pickle
1、概述pickle 为python中的序列化,反序列化模块,其局限是仅限于传输的两端都是python的情况,且尽量保持两端的版本一致。2、pickle包pickle包主要使用的4个函数为:

pickle.dump()将任意对象转化成bytes,并写入文件中。

pickle.dumps()将任意对象转化成bytes.

pickle.loads()从bytes中反序列化出对象

pickle.load()从文件中反序列出对象

其中dumps和dump是序列化方法,loads和load是反序列方法。dumps 和 dump 的区别在于:dumps 只接受一个参数即序列化的对象;dump 可以接受2个参数,一个是序列化的对象,另一个是需要写入的文件。pickle.dumps: 序列化一个对象
import pickle
a = [1, 2, 3]print(pickle.dumps(a)) # 序列化方法t = pickle.dumps(a)print(type(t))输出:

pickle.dump:序列化到一个文件中
import pickle
f = open('file.txt', 'wb')a = [7, 2, 9]pickle.dump(a, f) # 传递序列化对象和要存储的文件名f.close()# 读取序列化后的字节f = open('file.txt', 'rb') # 以二进制格式打开文件用于只读print(f.read())输出:

pickle.loads: 反序列化字节
import pickle
a = [1234]t = pickle.dumps(a)print(t)print(pickle.loads(t)) # 反序列化方法输出:

pickle.load: 反序列一个文件
import pickle
a = [88, 25, 520, 666]f = open('file.txt', 'wb')pickle.dump(a, f)f.close()f = open('file.txt', 'rb')t = pickle.load(f)f.close()print(t)输出:

3、实例下面是对实例对象进行序列化:
import pickle
d = dict(name='Sweety', sex='female', age=18)print(pickle.dumps(d))
f = open('file.txt', 'wb')d = dict(name='Sweety', sex='female', age=18)pickle.dump(d, f)f.close()f = open('file.txt', 'rb')d = pickle.load(f)f.close()print(d)输出:

我们可以看到变量的内容又回来了,但是这个变量和原来的变量是完全不相干的对象,它们只是内容相同而已。pickle 的问题就是它只能用于 Python,并且可能不同版本的 Python 彼此都不兼容,因此,只能用 Pickle 保存那些不重要的数据。
三、json
1、概述如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如 xml,但更好的方法是序列化为 json。因为 json表示出来是一个字符串,具有更好的可读性,是可以被各种语言读取的,也就方便了和其他语言间的传递。json是比XML快的,也能够在web页面读取,非常方便。2、json的数据类型Python和json内置的数据类型对应如下:
Python
json
dict
object
列表list或元组tuple
数组array
int或float
number
True/False
true/false
str
"string"
None
null
3、常用方法loads:是将string转换为dictdumps:是将dict转换为stringload:是将里json格式字符串转化为dict,读取文件dump:是将dict类型转换为json格式字符串,存入文件Python 内置的 json 模块提供了非常完善的 Python 对象到json格式的转换。
import json
d = {'a': 25, 'b': {'c': {'d': [1, 2, 3, 4, 5, 6]}}, 'e': True, 'f': False, 'g': None} # 构造字典json_str = json.dumps(d)print(d) # 输出字典print(json_str) # 对字典对象进行序列化print(json.loads(json_str)) # 对结果进行反序列化输出:

4、实例定义Teacher 类,然后序列化:
import json

class Teacher(object): def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age

a = Teacher('Sweety', 'female', 36)b = Teacher('Jack', 'male', 40)# 使用class对象的__dict__方法,将class的实例变为 dictprint(json.dumps(a, default=lambda obj: obj.__dict__))print(json.dumps(b, default=lambda obj: obj.__dict__))输出:

反序列化:我们要把 json反序列化为一个 Teacher对象实例,loads() 方法首先转换出一个 dict 对象,然后,我们传入的 object_hook 函数负责把 dict 转换为Teacher 实例:
def loadsteacher(d): return Teacher(d['name'], d['sex'], d['age'])

json_str1 = '{"name": "Sweety","age": 36, "sex": "female"}'json_str2 = '{"name": "Jack","age": 40, "sex": "male"}'obj1 = json.loads(json_str1, object_hook=loadsteacher)obj2 = json.loads(json_str2, object_hook=loadsteacher)print(obj1.__dict__)print(obj2.__dict__)输出:

读完本文,是不是基本掌握了Python中的序列化与反序列化呢?Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合 Web 标准,建议大家使用 json模块。


重磅福利!为了更好地服务各位同学的研究,爬虫俱乐部将在小鹅通平台上持续提供金融研究所需要的各类指标,包括上市公司十大股东、股价崩盘、投资效率、融资约束、企业避税、分析师跟踪、净资产收益率、资产回报率、国际四大审计、托宾Q值、第一大股东持股比例、账面市值比、沪深A股上市公司研究常用控制变量等一系列深加工数据,基于各交易所信息披露的数据利用Stata在实现数据实时更新的同时还将不断上线更多的数据指标。我们以最前沿的数据处理技术、最好的服务质量、最大的诚意望能助力大家的研究工作!相关数据链接,请大家访问:(https://appbqiqpzi66527.h5.xiaoeknow.com/homepage/10)或扫描二维码:


    最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。



对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!





往期推文推荐

      爬虫俱乐部的精彩答疑--爬虫为何失败?

       利用Stata批量制作学生证

     【数据分析-入门】科学计算基本库—Numpy的简单使用      Stata绘图系列——玩转绘图通用选项之图例     【基础篇】数据类型介绍——list、tuple和range对象

覆盖北交所的“cnstock”复工了!

高考热度大数据爬虫——谁才是院校顶流

跨框架数据操作

      河南大学经济学院2022年Stata数据处理与爬虫技术开班仪式顺利召开

爬虫俱乐部的精彩答疑——local function

爬虫俱乐部精彩答疑——Python中的三种文件读取方法爬虫俱乐部的精彩答疑--认真仔细方能写出好程序
爬虫俱乐部Python精彩答疑——更换Jupyter Notebook浏览器及dropna()参数详解
       爬虫俱乐部的精彩答疑--如何打开Excel中扩展名与文件源码不符的文件

解锁《梦华录》之东京繁华生活

爬虫俱乐部的精彩答疑——DOS命令

爬虫俱乐部的精彩答疑之换行问题

爬虫俱乐部的精彩答疑--路径设置乱码怎么破?

爬虫俱乐部的精彩答疑--putdocx的二三事

爬虫俱乐部精彩答疑之Python篇


关于我们 


   微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

   武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里
为作者署名,并有赏金分成。

2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可

以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。





您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存