序列化和反序列化 | 手把手教你入门Python之七十五

简介: 设计⼀套协议,按照某种规则,把内存中的数据转换为字节序列,保存到⽂件,这就是序列化,反之,从⽂件的字节序列恢复到内存中,就是反序列化。

上一篇:Sys模块的使用 | 手把手教你入门Python之七十四
下一篇:异常的概念 | 手把手教你入门Python之七十六

本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。

序列化和反序列化

通过⽂件操作,我们可以将字符串写⼊到⼀个本地⽂件。但是,如果是⼀个对象(例如列表、字典、元组等),就⽆法直接写⼊到⼀个⽂件⾥,需要对这个对象进⾏序列化,然后才能写⼊到⽂件⾥。

设计⼀套协议,按照某种规则,把内存中的数据转换为字节序列,保存到⽂件,这就是序列化,反之,从⽂件的字节序列恢复到内存中,就是反序列化。

Python中提供了JSON和pickle两个模块⽤来实现数据的序列化和反序列化。

JSON模块

JSON(JavaScriptObjectNotation, JS对象简谱)是⼀种轻量级的数据交换格式,它基于 ECMAScript 的⼀个⼦集,采⽤完全独⽴于编程语⾔的⽂本格式来存储和表示数据。JSON的本质是字符串!JSON里要使用双引号表示字符串。

使⽤JSON实现序列化

JSON提供了dump和dumps⽅法,将⼀个对象进⾏序列化。
dumps⽅法的作⽤是把对象转换成为字符串,它本身不具备将数据写⼊到⽂件的功能。

import json

file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
# file.write(names) 出错,不能直接将列表写⼊到⽂件⾥

# 可以调⽤ json的dumps⽅法,传⼊⼀个对象参数
result = json.dumps(names)

# dumps ⽅法得到的结果是⼀个字符串
print(type(result)) # <class 'str'>

# 可以将字符串写⼊到⽂件⾥
file.write(result)

file.close()

dump⽅法可以在将对象转换成为字符串的同时,指定⼀个⽂件对象,把转换后的字符串写⼊到这个⽂件⾥。

import json

file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']

# dump⽅法可以接收⼀个⽂件参数,在将对象转换成为字符串的同时写⼊到⽂件⾥
json.dump(names, file)
file.close()

注意:如果是⼀个空对象,调⽤dumps⽅法转换成为⼀个JSON对象,得到的结果是null(JS⾥的空对象)

json.dumps(None) # null

使⽤JSON实现反序列化

使⽤loads和load⽅法,可以将⼀个JSON字符串反序列化成为⼀个Python对象。

loads⽅法需要⼀个字符串参数,⽤来将⼀个字符串加载成为Python对象。

import json

# 调⽤loads⽅法,传⼊⼀个字符串,可以将这个字符串加载成为Python对象
result = json.loads('["zhangsan", "lisi", "wangwu", "jerry", "henry", "merry", "chris"]')
print(type(result)) # <class 'list'>

load⽅法可以传⼊⼀个⽂件对象,⽤来将⼀个⽂件对象⾥的数据加载成为Python对象。

import json

# 以可读⽅式打开⼀个⽂件
file = open('names.txt', 'r')

# 调⽤load⽅法,将⽂件⾥的内容加载成为⼀个Python对象
result = json.load(file)

print(result)
file.close()

pickle模块

和json模块类似,pickle模块也有dump和dumps⽅法可以对数据进⾏序列化,同时也有load和loads⽅法进⾏反序列化。区别在于,json模块是将对象转换成为字符串,⽽pickle模块是将对象转换成为⼆进制。

pickle模块⾥⽅法的使⽤和json⾥⽅法的使⽤⼤致相同,需要注意的是,pickle是将对象转换成为⼆进制,所以,如果想要把内容写⼊到⽂件⾥,这个⽂件必须要以⼆进制的形式打开。
序列化
dumps:将Python数据转化为二进制
dump:将Python数据转化为二进制,同时保存到指定文件

反序列化
loads:将二进制加载成为python数据
load:读取文件,并将文件的二进制内容加载成为python数据

import pickle

names = ['张三', '李四', '杰克', '亨利']
b_names = pickle.dumps(names)

file  = open('names.txt', 'wb')
file.write(b_names)   # 写入的是二进制
file.close()

file1 = open('names.txt', 'rb')
x = file1.read()
y = pickle.loads(x)
print(y)
file1.close()


file2 = open('names.txt', 'wb')
pickle.dump(names, file2)
file2.close()


file3 = open('names.txt', 'rb')
pickle.load(file3)
class Dog(object):
    def __init__(self, name, color):
        self.name = name
        self.color = color

     def eat(self):
        print(self.name + '正在吃东西')

d = Dog('大黄', '白色')

# 保存到文件里
pickle.dump(d, open('dog.txt', 'wb'))

# 从文件里加载出来
dd = pickle.load(d, open('dog.txt', 'rb'))
dd.eat()  

print(dd.name, dd.color)   # 大黄 白色

区别

思考: json和pickle两个模块都可以将对象进⾏序列化和反序列化,那它们有哪些区别,在使⽤场景上⼜该如何选择?

json模块:

  • 将对象转换成为字符串,不管是在哪种操作系统,哪种编程语⾔⾥,字符串都是可识别的。
  • json就是⽤来在不同平台间传递数据的。
  • 并不是所有的对象都可以直接转换成为⼀个字符串,下标列出了Python对象与json字符串的对应关系。

image.png

  • 如果是⼀个⾃定义对象,默认⽆法装换成为json字符串,需要⼿动指定JSONEncoder。
  • 如果是将⼀个json串重新转换成为对象,这个对象⾥的⽅法就⽆法使⽤了。
import json

class MyEncode(json.JSONEncoder):
    def default(self, o):
        # return {"name":o.name,"age":o.age}
        return o.__dict__

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

    def eat(self):
        print(self.name+'正在吃东⻄')

p1 = Person('zhangsan', 18)

# ⾃定义对象想要转换成为json字符串,需要给这个⾃定义对象指定JSONEncoder
result = json.dumps(p1, cls=MyEncode)
print(result) # {"name": "zhangsan", "age": 18}

# 调⽤loads⽅法将对象加载成为⼀个对象以后,得到的结果是⼀个字典
p = json.loads(result)
print(type(p))

pickle模块:

  • pickle序列化是将对象按照⼀定的规则转换成为⼆进制保存,它不能跨平台传递数据。
  • pickle的序列化会将对象的所有数据都保存。

配套视频

相关文章
|
6天前
|
Python
【python从入门到精通】-- 第五战:函数大总结
【python从入门到精通】-- 第五战:函数大总结
27 0
|
23小时前
|
存储 算法 Python
【10月更文挑战第16天】「Mac上学Python 27」小学奥数篇13 - 动态规划入门
本篇将通过 Python 和 Cangjie 双语介绍动态规划的基本概念,并解决一个经典问题:斐波那契数列。学生将学习如何使用动态规划优化递归计算,并掌握编程中的重要算法思想。
32 3
|
3天前
|
设计模式 开发者 Python
Python编程中的设计模式:从入门到精通####
【10月更文挑战第14天】 本文旨在为Python开发者提供一个关于设计模式的全面指南,通过深入浅出的方式解析常见的设计模式,帮助读者在实际项目中灵活运用这些模式以提升代码质量和可维护性。文章首先概述了设计模式的基本概念和重要性,接着逐一介绍了几种常用的设计模式,并通过具体的Python代码示例展示了它们的实际应用。无论您是Python初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和实用的技巧。 ####
|
5天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
【10月更文挑战第12天】本文介绍了如何使用Python和Scikit-learn进行机器学习的基础知识和入门实践。首先概述了机器学习的基本概念,包括监督学习、无监督学习和强化学习。接着详细讲解了Python和Scikit-learn的安装、数据处理、模型训练和评估等步骤,并提供了代码示例。通过本文,读者可以掌握机器学习的基本流程,并为深入学习打下坚实基础。
11 1
|
6天前
|
自然语言处理 Python
【python从入门到精通】-- 第三战:输入输出 运算符
【python从入门到精通】-- 第三战:输入输出 运算符
34 0
【python从入门到精通】-- 第三战:输入输出 运算符
|
5天前
|
机器学习/深度学习 人工智能 架构师
Python学习圣经:从入门到精通Python,打好 LLM大模型的基础
Python学习圣经:从0到1精通Python,打好AI基础
|
5天前
|
数据可视化 定位技术 Python
Python数据可视化--Matplotlib--入门
Python数据可视化--Matplotlib--入门
12 0
|
5天前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--入门
Python数据分析篇--NumPy--入门
16 0
|
5天前
|
IDE 开发工具 索引
Python基础知识---入门
Python基础知识---入门
5 0
|
6天前
|
程序员 Python
【python从入门到精通】-- 第四战:语句汇总
【python从入门到精通】-- 第四战:语句汇总
17 0