[Python学习日记-50] Python 中的序列化模块 —— pickle 和 json

[Python学习日记-50] Python 中的序列化模块 —— pickle 和 json

简介

pickle 模块

json 模块

pickle VS json

简介

        什么叫序列化?

        序列化指的是将对象转换为可以在网络上传输或者存储到文件系统中的字节流的过程。序列化使得对象可以被保存、传输和恢复,而不损失其状态和属性。在序列化过程中,对象的属性和数据会被编码为二进制数据,以便能够在不同的环境中被解码和重建成原来的对象。常见的序列化格式有 JSON、XML 和二进制格式等。简单来说就是把内存里的数据类型转换成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受以字节(bytes)的形式进行存储或传输。

        有了序列化,那有没有反序列化呢?

        当然有了,反序列化是序列化的逆过程,指的是将序列化后的字节流重新转换为对象的过程。通过反序列化,可以将保存在文件系统或者网络中的对象数据重新还原为内存中的对象,使其恢复原有的状态和属性。反序列化过程将二进制数据解码并重新构建为原始对象,并将其存储在内存中,以便程序可以直接使用这些对象。反序列化是序列化的重要补充,它使得可以在不同的环境或者平台之间传递对象数据,并在接收方重新构建对象。简单来说就是把存储在硬盘当中的字节或者是网络传输过来的字节转换为相应的数据类型,使其能在对应的程序中使用传输过来的数据。

        其实这个过程非常像科幻电影里面的光速移动,先把人编码为光信号,然后传输到目的地,最后在目的地接收该光信号,然后通过光信号中的信息,把人还原回来。

        有的小伙伴还是不明白,为什么要这么大费周章的进行序列化呢?我们举个例子,例如你在打《使命召唤》,在这个过程中打累了,想要停下来关掉游戏2天再玩,在2天之后游戏又从你上次停止的地方继续运行,那你上次游戏的进度肯定保存在硬盘上了,不然你电脑一断电内存里的数据肯定就没了,它是以何种形式来存储的呢?而且游戏过程中产生的很多临时数据都是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存里,而这些都需要存下来,那该怎么存呢?把列表变成文件里的多行多列形式?但是嵌套字典根本没法以该形式进行储存啊。所以,若是有种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,还是原来的格式的话,那是极好的。而这个需求恰恰就是序列化模块的功能了,在 Python 中有两个序列化模块:pickle(用于 Python 特有的类型和 Python 的数据类型间进行转换)和 json(用于字符串和 Python 数据类型间进行转换),下面我们分别来看看他们的用法。

pickle 模块

        pickle 模块提供了四个功能:dumps、dump、loads、load

一、序列化

  • dumps:生成序列化的字符串在内存当中,代码如下
import pickle

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

d_dump = pickle.dumps(d)    # 序列化
print(d_dump)

代码输出如下:

  • dump:生成序列化的字符串并写入文件,代码如下
import pickle

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

f = open('game.pkl','wb')    # pickle 序列化后是字节,所以需要用 wb,读需要用 rb
pickle.dump(d,f) # 序列化存入文件
pickle.dump(alive_players,f)

代码效果如下:

        之所以是乱码,是因为 PyCharm 想要以 UTF-8 强行解码导致的。  

二、反序列化

  • loads:把内存当中的序列化字符串进行反向解析,代码如下
import pickle

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

d_dump = pickle.dumps(d)    # 序列化
print(d_dump)
print(pickle.loads(d_dump))    # 反序列化

代码输出如下:

  • load:从文件加载序列化的字符串反向解析到内存当中,代码如下
'''
game.pkl 内容:
\x80\x04\x95=\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x04jove\x94\x8c\x04role\x94\x8c\x06police\x94\x8c\x05blood\x94KL\x8c\x06weapon\x94\x8c\x04M4A1\x94u.
'''

import pickle


f = open('game.pkl','rb')
# First in first out --> FIFO 先入先出
# First in last out --> FILO 先入后出
d = pickle.load(f)    # 反序列化,从文件取出来
print(d)
alive_plays = pickle.load(f)
print(alive_plays)

代码输出如下: 

        结合上面序列化存入文件时的代码输出,我们知道 pickle 模块在多个数据类型进行序列化的时候,是 First in first out(FIFO)类型的,即先先入先出。

json 模块

        json 模块也提供了四个功能:dumps、dump、loads、load,用法跟 pickle 一致

一、序列化

  • dumps:生成序列化的字符串在内存当中,代码如下
import json

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

d_dump = json.dumps(d)

print(d_dump)
print(type(d_dump))    # pickle是bytes,但json是str

代码输出如下:

  • dump:生成序列化的字符串并写入文件,代码如下
import json

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

f = open('game.json','w')    # json.dumps(d)转换为的是str,所以只需要'w'就可以了

json.dump(d,f)

代码效果如下:

二、反序列化

  •  loads:把内存当中的序列化字符串进行反向解析,代码如下
import json

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

d_dump = json.dumps(d)
print(type(d_dump))
d_load = json.loads(d_dump)
print(d_load["weapon"])

代码输出如下:

  •  load:从文件加载序列化的字符串反向解析到内存当中,代码如下
'''
game.json 内容:
{"name": "jove", "role": "police", "blood": 76, "weapon": "M4A1"}
'''

import json

f = open('game.json','r')

d = json.load(f)
print(d,type(d))
print(d["weapon"])

代码输出如下:

pickle VS json

Pickle:

优点:专为 Python 设计,支持 Python 所有的数据类型,例如class->object、function、datetime等
缺点:只能在 Python 中使用,而且存储数据占空间大

JSON:

优点:跨语言(不同编程语言之间的数据传递可用 json 交接)、存储数据占空间小
缺点:只能支持 int、str、list、tuple、dict 这类比较常规的数据类型

一、dump 次数

        pickle 可以 dump 多次,json 只能 dump 一次,主要问题是出现在读取的时候,分别使用 pickle 和 json 进行多次 dump,game.pkl 和 game.json,代码如下

import pickle
import json

d = {
    "name":"jove",
    "role":"police",
    "blood":76,
    "weapon":"M4A1"
}

alive_players = ["jove","kerry","lucy"]

f_p = open('game.pkl','wb')
pickle.dump(d,f_p)
pickle.dump(alive_players,f_p)

f_j = open('game.json','w')
json.dump(d,f_j)
json.dump(alive_players,f_j)

代码效果如下:

        可以看到,数据已经成功序列化后写入到硬盘当中了,这时候我们来把数据 load 出来看看问题到底是什么,代码如下

import pickle
import json

f_p = open("game.pkl","rb")
print("pickle1:",pickle.load(f_p))
print("pickle2:",pickle.load(f_p))

f_j = open("game.json","r")
print("json1:",json.load(f_j))
print("json2:",json.load(f_j))

代码输出如下:

        从输出结果来看,很明显 json 不能像 pickle 一样进行多次 dump,这是与 json 的文件写入有关,我们在仔细看看 json 进行多次 dump 之后写入的到底是什么,看下图

        多次 dump 的写入内容都是拼在一起的,并没有什么特殊字符用作分割,所以 json.load 尝试反向解析的时候就会把全部 game.json 里面的内容都读出来,但是它发现这个并不认识,所以最终就会抛出 json.decoder.JSONDecodeError 的错误,即 json 解码失败。

二、pickle 序列化非常规数据类型

        我们以 datetime 对象为例,分别使用 pickle 和 json 进行 dump 操作,代码如下

import pickle
import json
import datetime

t = datetime.datetime.now()
print(t,type(t))
tp_dump = pickle.dumps(t)
print(tp_dump)
tj_dump = json.dumps(t)

代码输出如下:

        从输出结果来看,很明显 json 不能像 pickle 一样序列化 datetime 对象,而是直接抛出 TypeError 报错,这是因为 json 的其中一个特性就是跨语言,而不同语言之间的语法定义都是不一样的,如果需要把所有语言的语法定义都进行识别然后转换,那这个工作将会无比复杂,所以 json 就干脆只支持一些常规的数据类型,因为这些数据类型几乎在所有语言当中都有。

        再举个实际场景,例如我要开发一个网站,而网站是分前后端的,前端我们使用的语言是 html、js、css,而后端我们使用的是 Python 那如果我们要进行对接那应该怎么做呢?能把整个 function 序列化到前端语言中运行吗?这显然是不行的,我们以 js 和 Python 为例来对比一下

js 中定义的 function:

fName (x,x,x){
        xxxx
}

 

Python 中定义的 function:

def fname():

        xxxxx

        可以很明显的看出,两种语法完全不同,而 json 是需要先把数据类型转换为字符串,然后在进行传输或储存的,最后原封不动的传到取其他语言当中。而当其他语言拿到了传过来的 json 文件时惊呆了,这个 function 的语法居然是它不认识的,那它只能无奈的报错了。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/895833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习与神经网络:科技的星辰大海

前提 近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一…

基于K8S的StatefulSet部署mysql主从

StatefulSet特性 StatefulSet的网络状态 拓扑状态:应用的多个实例必须按照某种顺序启动,并且必须成组存在,例如一个应用中必须存在一 个A Pod和两个B Pod,且A Pod必须先于B Pod启动的场景 存储状态:应用存在多个实例…

ChatGPT01-preivew体验报告:内置思维链和多个llm组合出的COT有啥区别呢?丹田与练气+中学生物理奥赛题测试,名不虚传还是名副其实?

一个月前,o1发布的时候,我写了篇文章介绍 逻辑推理能力堪比博士生,OpenAI发布全新AI模型系列: o1 - 大模型或许进入新阶段,还翻译了官方的介绍 解密OpenAI o1是如何让LLMs获得逻辑推理能力的 - CoT * RL,也…

【Linux】多线程安全之道:互斥、加锁技术与底层原理

目录 1.线程的互斥 1.1.进程线程间的互斥相关背景概念 1.2.互斥量mutex的基本概念 所以多线程之间为什么要有互斥? 为什么抢票会抢到负数,无法获得正确结果? 为什么--操作不是原子性的呢? 解决方式: 2.三种加锁…

基于SpringBoot+Vue的厨艺交流系统的设计与实现(源码+定制开发)厨艺知识与美食交流系统开发、在线厨艺分享与交流平台开发、智能厨艺交流与分享系统开发

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

第五届人工智能与教育国际学术会议(ICAIE 2024)

文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网:https://ais.cn/u/vEbMBz提交检索:EI Compendex、IEEE Xplore、Scopus 三、大会介绍 第五届人工智能与教育国际学术会议&#x…

java逻辑运算符 C语言结构体定义

1. public static void main(String[] args) {System.out.println(true&true);//&两者均为true才trueSystem.out.println(false|false);// | 两边都是false才是falseSystem.out.println(true^false);//^ 相同为false,不同为trueSystem.out.println(!false)…

【python爬虫实战】爬取全年天气数据并做数据可视化分析!附源码

由于篇幅限制,无法展示完整代码,需要的朋友可在下方获取!100%免费。 一、主题式网络爬虫设计方案 1. 主题式网络爬虫名称:天气预报爬取数据与可视化数据 2. 主题式网络爬虫爬取的内容与数据特征分析: - 爬取内容&am…

蜜罐技术的出现究竟影响了什么

自网络诞生以来,攻击威胁事件层出不穷,网络攻防对抗已成为信息时代背景下的无硝烟战争。然而,传统的网络防御技术如防火墙、入侵检测技术等都是一种敌暗我明的被动防御,难以有效应对攻击者随时随地发起的无处不在的攻击和威胁。蜜…

IO多路复用概述与epoll简介

一、引言 在网络编程中,高并发的场景下处理大量连接请求是一项挑战。传统的阻塞式IO模型会让线程在等待数据的过程中陷入停顿,导致系统效率低下。为了解决这个问题,IO多路复用应运而生。它允许一个线程同时监听多个文件描述符(如…

Gin框架操作指南02:JSON渲染

官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/ 注:本教程采用工作区机制,所以一个项目下载了Gin框架,其余项目就无需重复下载,想了解的读者可阅读第一节:Gin操作指南&#…

qt creator 开发环境的安装

1.找官网 官网地址:Installation | Qt Creator Documentation 点 Parent Directory 继续点 Parent Directory 点 archive/ 2.下载在线安装器 点 online_ainstallers 选择在线安装器版本 选择对应版本后进入下载列表,根据自己的系统选择下载。 下载后…

DreamFace 4.7.1 | 图片说话,数字人

DreamFace是一款可以把静态图片变成动态视频的软件,操作简单,内置多种模板可供选择。此外,还支持将图片变得更清晰或者转换成卡通风格等功能,非常适合喜欢创意视频制作的用户。通过安装软件后,根据提示选择需要转换的静…

c++ pdf文件提取txt文本示例

最近抽空采用之前封装的接口将pdf文件提取出txt文本,顺利完成,界面如下所示: 提起的效果如下所示: 输出的txt文本内容如下: 下载链接:https://download.csdn.net/download/u011269801/89905548

vue中如何检测数组变化(vue基础,面试,源码级讲解)

大家有什么不明白的地方可以分享在评论区,大家一起探讨哦~~ (如果对数据劫持还有所不明白的小伙伴,可以去看看上一篇文章哦) 在vue2中,是如何对数组进行劫持的呢? 简单代码实现: 在vue2中&…

pytorh学习笔记——cifar10(三)模仿VGGNet创建卷积网络

VGG16是由牛津大学视觉几何组(Visual Geometry Group)提出的一种深度卷积神经网络模型。 VGGNet 探索了卷积神经网络的深度与其性能之间的关系,成功地构筑了 16~19 层深的卷积神经网络,同时拓展性又很强,迁移到其它图片…

反转链表 K个一组翻转链表

目录 LeetCode206 反转链表 LeetCode92 反转链表II LeetCode25 K个一组翻转链表 LeetCode206 反转链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x)…

poisson过程——随机模拟(Python和R实现)

Python实现 exponential()使用,自动poisson过程实现。 import numpy as np import matplotlib.pyplot as plt# Parameters lambda_rate 5 # rate parameter (events per time unit) T 10 # total time# Generate Poisson process times np.random.exponential(…

PCL 点云配准 Trimed-ICP算法(精配准

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 perform_standard_icp 函数 2.1.2 perform_trimmed_icp 函数 2.1.3 visualize_registration 函数 2.2完整代码 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算…

软件设计模式------简单工厂模式

简单工厂模式(Simple factory Pattern),又称静态工厂方法(Static Factory Method),属于创新型模式,但它不属于GoF23个设计模式其一。 一、模式动机: 有时需要创建一些来自相同父类的类的实例。 二、定义&#xff1a…