一、背景描述
在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.JSONEncoder
和 json.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
, dumps
,load
,loads
,其中的差别也一样,我们不在赘述,这里我们给出我们的序列化方法
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
的优势:
- 支持序列化几乎所有的 Python 对象,包括自定义类、函数、以及多个对象之间的引用关系。
- 保存对象的状态、方法和类信息等,可以在反序列化后完全恢复对象的原始结构。
- 序列化和反序列化过程相对简单,只需调用
dump()
和load()
方法即可。
pickle
的劣势:
- 由于
pickle
是针对 Python 特定的格式,不能跨语言使用。其他编程语言可能无法正确解析pickle
生成的数据。 pickle
生成的序列化数据通常较大,存储空间消耗较高。
json
的优势:
json
是一种通用的数据交换格式,几乎所有编程语言都支持解析和生成 JSON 格式的数据。- 生成的 JSON 数据相对较小,存储空间消耗相对较低。
- 人类可读性好,易于理解和调试。
json
的劣势:
- 只能序列化一部分简单的数据类型,如字典、列表、字符串、数值等基本类型,不支持序列化自定义的复杂对象和函数。
- 只能保存数据的值,丢失了对象的状态、方法和类信息等。