详解Python 序列化结果

  • Post category:Python

Python序列化是指将Python对象转换为字节流的过程,以便可以将这些字节流存储在磁盘上或通过网络传输。 Python标准库中的pickle模块提供了在Python中序列化和反序列化对象的功能。

序列化结果的数据类型

pickle序列化后的结果是bytes类型的字节流,而json序列化后的结果是str类型的JSON格式字符串。

pickle序列化的步骤

pickle序列化的步骤如下:

  1. 导入pickle模块
import pickle
  1. 将Python对象转换为字节流
data = {"name": "Tom", "age": 18}
bytes_data = pickle.dumps(data)
  1. 将字节流存储到磁盘或通过网络传输
# 存储到磁盘
with open('data.pickle', 'wb') as f:
    f.write(bytes_data)

# 通过网络传输
# 例如,将字节流发送给另一个进程
another_process.recv(bytes_data)
  1. 反序列化字节流
# 从磁盘读取字节流并反序列化
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序列化有一些限制:

  1. pickle序列化只能用于Python环境,因为pickle序列化的结果包含了Python对象的一些内部信息,例如对象的类名、属性名等。如果使用不同版本的Python解释器反序列化pickle数据,可能会因为环境不同导致反序列化失败。

  2. pickle序列化并不安全,因为pickle序列化的结果可以包含可执行的Python代码。因此,不要在不信任的环境下反序列化pickle数据。

JSON序列化的过程

JSON序列化的过程与pickle序列化类似。

  1. 导入json模块
import json
  1. 将Python对象转换为JSON格式字符串
data = {"name": "Tom", "age": 18}
json_str = json.dumps(data)
  1. 将JSON格式字符串存储到磁盘或通过网络传输
# 存储到磁盘
with open('data.json', 'w') as f:
    f.write(json_str)

# 通过网络传输
# 例如,将JSON格式字符串发送给另一个进程
another_process.recv(json_str.encode('utf-8'))
  1. 反序列化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()