python数据序列化之json与pickle

一、背景描述

在python下做了一个仿真,但是仿真时间比较长,每次想看点中间的数据都需要重新跑一下,所以想个办法,把这些数据都保存下来,想看的时候直接load进去就可以了。

这里我首先想到的就是json,然后发现JSON有一些事情是做不了的或者说很麻烦,所以又找到了pickle。

二、JSON

json是一种轻量级的数据交换格式,是JavaScript的子集。本来这种数据格式是用来代替xml的,现在也基本证明他能做到。这里介绍一下它的用法。

2.1、将 Python 对象转换为 JSON 字符串

有两种方法完成这个任务,分别是dumps与dump。

首先介绍dumps:

import json

data = {
    
    'a': 1, 'b': 'name'}
str = json.dumps(data)
print(str)

它是将python的对象序列化成了一个字符串。

然后介绍dump:

import json

data = {
    
    'a': 1, 'b': 'name'}
with open('data.json','wb') as f:
	json.dump(data,f)

它是将python的对象序列化,并写入了文件。

区别:这两者之间其实就是一个序列化成了字符串一个序列化成了文件,dumps中多出的s就可以认为是string字符串。

2.2、将 JSON 字符串转换为 Python 对象

和上面的内容是相反的,也有两个接口,分别是loads和load,聪明的读者已经猜出来了,一个是将字符串反序列化,一个是将文件反序列化。

import json

data = json.loads(str)
print(data)
import json

with open('data.json', 'rb') as f:
    data = json.load(f)

2.3、自定义json解码器和编码器

可以通过继承 json.JSONEncoderjson.JSONDecoder 类来自定义 JSON 编码器和解码器。

import json

# 自定义 JSON 编码器
class PersonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Person):
            return {
    
    'name': obj.name, 'age': obj.age}
        return super().default(obj)

# 自定义 JSON 解码器
class PersonDecoder(json.JSONDecoder):
    def __init__(self, *args, **kwargs):
        super().__init__(object_hook=self.object_hook, *args, **kwargs)

    def object_hook(self, dct):
        if 'name' in dct and 'age' in dct:
            return Person(dct['name'], dct['age'])
        return dct

# 定义 Person 类
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 使用自定义编码器和解码器
data = [Person('Alice', 25), Person('Bob', 30)]
json_str = json.dumps(data, cls=PersonEncoder)
data = json.loads(json_str, cls=PersonDecoder)

但是这种定义方式很麻烦,并且依旧无法处理很复杂的数据,只是对一些较复杂数据提供了一种处理方式。我们不在详细解读(我也不会了)。

三、pickle

pickle也提供了上面的哪四种方法 dump, dumpsloadloads,其中的差别也一样,我们不在赘述,这里我们给出我们的序列化方法

import numpy as np
import pickle


# 定义包含 NumPy 数组的 Python 对象
class DataObject:
    def __init__(self):
        self.array = np.zeros(100,dtype='float64')
        self.age = 0
        self.name = 'name'
    
    def reset(self):
        self.age = 100
        self.name = 'ale'
        


data = DataObject();
# 序列化对象到文件
with open('serialized_data.pkl', 'wb') as file:
    pickle.dump(data, file)

with open('serialized_data.pkl', 'rb') as file:
    data2 = pickle.load(file)

data2.reset()

print(data2.array)
print(data2.age)
print(data2.name)

运行上面这段程序我们发现可以进行序列化与反序列化,那他们之间的优势与劣势呢

四、优劣

pickle 的优势:

  1. 支持序列化几乎所有的 Python 对象,包括自定义类、函数、以及多个对象之间的引用关系。
  2. 保存对象的状态、方法和类信息等,可以在反序列化后完全恢复对象的原始结构。
  3. 序列化和反序列化过程相对简单,只需调用 dump()load() 方法即可。

pickle 的劣势:

  1. 由于 pickle 是针对 Python 特定的格式,不能跨语言使用。其他编程语言可能无法正确解析 pickle 生成的数据。
  2. pickle 生成的序列化数据通常较大,存储空间消耗较高。

json 的优势:

  1. json 是一种通用的数据交换格式,几乎所有编程语言都支持解析和生成 JSON 格式的数据。
  2. 生成的 JSON 数据相对较小,存储空间消耗相对较低。
  3. 人类可读性好,易于理解和调试。

json 的劣势:

  1. 只能序列化一部分简单的数据类型,如字典、列表、字符串、数值等基本类型,不支持序列化自定义的复杂对象和函数。
  2. 只能保存数据的值,丢失了对象的状态、方法和类信息等。

猜你喜欢

转载自blog.csdn.net/weixin_43903639/article/details/131622256