在编程的世界里,我们常常会遇到这样一个问题:如何保存程序中的数据,尤其是当你需要在程序结束后保留变量的值,或者在不同的程序之间传递数据时。幸运的是,Python给我们提供了两位超级英雄来帮忙——Pickle和JSON!今天我们就来聊一聊这两个模块,它们不仅能帮你序列化和反序列化数据,还能让你轻松应对跨程序、跨机器的数据传输需求。

一、先来认识一下Pickle
Pickle是Python自家的序列化模块,它的工作就是把内存中的数据转化为一种便于存储和传输的格式。我们称这个过程为序列化,而反过来,把这些数据重新加载回内存,则叫做反序列化。
Pickle的使用
想象一下,你有一个字典对象 d = dict(name='Bob', age=20, score=88),它可不是一块静态的代码,而是驻扎在内存中的一片“神奇领土”。程序运行时,你可以随意修改它的内容,但一旦程序结束,它就会消失。为了让它永存,你需要把它保存到硬盘上。Pickle就能帮你做到这一点!
让我们来尝试一下:
pythonimport pickled = dict(name='Bob', age=20, score=88)# 序列化:把字典转化为二进制数据pickled_data = pickle.dumps(d)print(pickled_data)
你会看到一串类似乱码的二进制数据,这其实是Pickle为你处理过的对象数据。你也可以直接将它保存到文件里:
python# 序列化并保存到文件with open('dump.txt', 'wb') as f:pickle.dump(d, f)
然后,如何读取这个文件并恢复数据呢?简单!只需要用 pickle.load() 就能完成反序列化:
pythonwith open('dump.txt', 'rb') as f:d_new = pickle.load(f)print(d_new) # 输出:{'name': 'Bob', 'age': 20, 'score': 88}
这时你会发现,d_new 和最初的字典内容完全一样!不过,它们并不是同一个对象,它们只是数据相同而已。
Pickle的缺点
然而,Pickle有个致命的缺点——它只适用于Python,而且不同版本的Python之间可能存在不兼容的问题。所以,Pickle适合用来保存一些不重要的数据,或者在相同环境下进行数据传输。
二、从Pickle到JSON:跨语言的魔法
Pickle虽好,但不能跨语言使用,怎么办?别担心,JSON来救场!JSON(JavaScript Object Notation)是目前最常用的跨语言数据交换格式,它不仅轻量,而且几乎支持所有编程语言。Python的json模块可以让我们方便地将Python对象转换为JSON格式。
JSON的使用
JSON的结构看起来像这样:
-
字典
{}转换成dict -
列表
[]转换成list -
字符串
"string"转换成str -
数字
1234.56转换成int或float -
布尔值
true/false转换成True/False -
空值
null转换成None
让我们来看看如何将Python字典对象转换成JSON:
pythonimport jsond = dict(name='Bob', age=20, score=88)# 序列化为JSON字符串json_str = json.dumps(d)print(json_str) # 输出:{"name": "Bob", "age": 20, "score": 88}
你会看到输出的就是标准的JSON格式字符串!如果要将其保存到文件里,可以使用json.dump()方法。
pythonwith open('dump.json', 'w') as f:json.dump(d, f)
而反序列化操作也非常简单:
pythonwith open('dump.json', 'r') as f:d_new = json.load(f)print(d_new) # 输出:{'name': 'Bob', 'age': 20, 'score': 88}
处理自定义对象的JSON序列化
你可能会遇到需要序列化自定义类的情况,JSON直接无法处理类实例对象。比如我们定义一个Student类:
pythonclass Student:def __init__(self, name, age, score):self.name = nameself.age = ageself.score = scores = Student('Bob', 20, 88)
直接尝试序列化:
pythonjson_str = json.dumps(s)
会得到一个错误,提示 TypeError: ... is not JSON serializable。
解决方法:我们可以通过提供一个 default 参数来指定如何将 Student 实例转换为JSON:
pythondef student_to_dict(student):return {'name': student.name,'age': student.age,'score': student.score}print(json.dumps(s, default=student_to_dict))
这样就可以把自定义对象转换为可序列化的字典,再转化为JSON了。
高级用法
如果你想偷个懒,把所有自定义对象都转化为字典,可以用lambda函数:
pythonprint(json.dumps(s, default=lambda obj: obj.__dict__))
这样,Student类的实例就会自动被转换为一个字典,这样JSON就可以轻松处理了。
三、练习题:手把手教你玩转Pickle与JSON
任务1:使用Pickle保存和加载数据
-
创建一个字典
d = dict(name='Alice', age=25, score=90),使用Pickle将其序列化并保存到文件中。 -
在另一个Python程序中,读取保存的Pickle文件,反序列化并打印出内容。
任务2:将自定义对象转换为JSON格式
-
定义一个
Book类,包含title(书名)、author(作者)、price(价格)三个属性。 -
创建一个
Book实例,并尝试将其转化为JSON格式。 -
使用
lambda函数简化转换过程,使得所有类的实例都可以自动转化为字典并序列化为JSON。
任务3:中文字符的JSON处理
-
创建一个包含中文字符的字典:
{'name': '小明', 'age': 20}。 -
使用
json.dumps()方法序列化该字典,观察ensure_ascii参数对结果的影响,并打印输出。
* 小结
今天我们学习了如何使用Pickle和JSON来实现数据的序列化和反序列化。Pickle适用于Python内部使用,而JSON则是跨语言的通用标准。当你需要将数据保存到磁盘、传输数据或进行远程通信时,这两个工具都是不可或缺的!
准备好进入Python数据序列化的世界了吗?快来动手做一做练习吧!
1462

被折叠的 条评论
为什么被折叠?



