Python序列化是指将Python对象转换为字节流的过程,以便可以将这些字节流存储在磁盘上或通过网络传输。 Python标准库中的pickle模块提供了在Python中序列化和反序列化对象的功能。
序列化结果的数据类型
pickle序列化后的结果是bytes类型的字节流,而json序列化后的结果是str类型的JSON格式字符串。
pickle序列化的步骤
pickle序列化的步骤如下:
- 导入pickle模块
import pickle
- 将Python对象转换为字节流
data = {"name": "Tom", "age": 18}
bytes_data = pickle.dumps(data)
- 将字节流存储到磁盘或通过网络传输
# 存储到磁盘
with open('data.pickle', 'wb') as f:
f.write(bytes_data)
# 通过网络传输
# 例如,将字节流发送给另一个进程
another_process.recv(bytes_data)
- 反序列化字节流
# 从磁盘读取字节流并反序列化
with open('data.pickle', 'rb') as f:
bytes_data = f.read()
data = pickle.loads(bytes_data)
# 从另一个进程接收字节流并反序列化
bytes_data = another_process.recv()
data = pickle.loads(bytes_data)
pickle序列化的限制
需要注意的是,pickle序列化有一些限制:
-
pickle序列化只能用于Python环境,因为pickle序列化的结果包含了Python对象的一些内部信息,例如对象的类名、属性名等。如果使用不同版本的Python解释器反序列化pickle数据,可能会因为环境不同导致反序列化失败。
-
pickle序列化并不安全,因为pickle序列化的结果可以包含可执行的Python代码。因此,不要在不信任的环境下反序列化pickle数据。
JSON序列化的过程
JSON序列化的过程与pickle序列化类似。
- 导入json模块
import json
- 将Python对象转换为JSON格式字符串
data = {"name": "Tom", "age": 18}
json_str = json.dumps(data)
- 将JSON格式字符串存储到磁盘或通过网络传输
# 存储到磁盘
with open('data.json', 'w') as f:
f.write(json_str)
# 通过网络传输
# 例如,将JSON格式字符串发送给另一个进程
another_process.recv(json_str.encode('utf-8'))
- 反序列化JSON格式字符串
# 从磁盘读取JSON格式字符串并反序列化
with open('data.json', 'r') as f:
json_str = f.read()
data = json.loads(json_str)
# 从另一个进程接收JSON格式字符串并反序列化
json_str = another_process.recv()
data = json.loads(json_str)
需要注意的是,JSON格式字符串只能包含一些基本的数据类型(例如字符串、数字、布尔值、数组和字典),而不能包含函数、自定义类等Python中的一些特殊类型。
示例
接下来提供两个示例,分别对应Python序列化和JSON序列化的应用:
示例1
下面的示例演示了如何使用pickle序列化一个自定义的Python类Circle,并存储到磁盘。
import pickle
class Circle:
def __init__(self, r):
self.r = r
self.c = 2 * 3.14 * r
c = Circle(10)
# 序列化Circle对象
bytes_data = pickle.dumps(c)
# 存储到磁盘
with open('circle.pickle', 'wb') as f:
f.write(bytes_data)
# 从磁盘读取Circle对象,并反序列化
with open('circle.pickle', 'rb') as f:
data = pickle.loads(f.read())
# 检查反序列化后的对象的类型和属性是否正确
assert isinstance(data, Circle)
assert data.r == 10
assert data.c == 62.8
示例2
下面的示例演示了如何使用json序列化一个字典,并将其发送给另一个进程。
import json
import multiprocessing as mp
def worker(q):
# 接收通过队列发送过来的JSON格式字符串
json_str = q.get()
data = json.loads(json_str)
# 检查反序列化后的字典是否正确
assert data == {"name": "Tom", "age": 18}
q.task_done()
if __name__ == '__main__':
# 创建一个队列用于进程间通信
q = mp.JoinableQueue()
# 创建一个子进程,并将队列传给子进程
p = mp.Process(target=worker, args=(q,))
p.start()
# 将JSON格式字符串发送给子进程
json_str = json.dumps({"name": "Tom", "age": 18})
q.put(json_str)
# 等待子进程处理完毕
q.join()
p.join()