如何序列化Python类?
在Python编程中,我们常常需要将类对象或实例对象序列化。序列化即将数据转换成可以存储或传输的格式,常见的格式有JSON、XML、pickle等。但对于类对象或实例对象的序列化可能需要一些额外的处理。接下来将介绍如何将Python类序列化。
阅读更多:Python 教程
Pickle模块
pickle模块是Python标准库中的模块,它可以将Python对象序列化成一个字节序列,也可以将字节序列反序列化成Python对象。在使用pickle进行序列化时,需要注意以下几点:
- pickle只能在Python中使用,如果需要与其他语言通信,建议使用JSON或XML等通用格式。
-
pickle序列化后的数据是二进制的,不可读,不可修改。
-
在反序列化时,必须要保证序列化和反序列化的过程使用的是同一个python版本和语言环境。
例如,我们定义一个示例类People,包含姓名、年龄、性别三个属性。
import pickle
class People(object):
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
序列化类
我们可以使用pickle将类对象People序列化。
p = People('Tom', 20, 'Male')
with open('people.pkl', 'wb') as f:
pickle.dump(p, f)
上述代码中,我们将类对象p序列化并保存到people.pkl文件中。pickle.dump方法接收两个参数,第一个参数为要序列化的对象,第二个参数为文件对象,文件通常以二进制写入模式打开。
反序列化类
接下来可以将序列化后的数据反序列化成原来的类对象。
with open('people.pkl', 'rb') as f:
p_load = pickle.load(f)
print(p_load.name, p_load.age, p_load.gender)
上述代码中,我们打开上一步保存的文件people.pkl,并使用pickle.load方法将数据反序列化成原对象。反序列化后,我们可以调用对象的属性和方法。
JSON模块
JSON是一种轻量级的数据交换格式,可以描述Python中的数据类型,如字符串、数字、列表、字典等。JSON格式可以被任何语言读取和生成,具有通用性。Python中的json模块提供了方法将Python对象序列化成JSON格式,也可以将JSON格式反序列化成Python对象。
然而,JSON格式有一个限制——只支持基本的数据类型,如字符串、数字、布尔型、列表和字典,而不支持类对象或实例对象的序列化。因此,如果需要将Python中的自定义类对象序列化成JSON格式,需要进行一些额外的操作。
在以下示例中,我们继续使用上面定义的类People。
序列化类
首先需要定义一个序列化函数,将自定义的类对象转换成字典格式,再调用json.dumps方法将字典序列化成JSON格式。
import json
def serialize(obj):
if isinstance(obj, People):
return {'name': obj.name, 'age': obj.age, 'gender': obj.gender}
else:
raise TypeError(f'{obj} is not JSON serializable')
p = People('Tom', 20, 'Male')
serialized_p = json.dumps(p, default=serialize)
print(serialized_p)
上述代码中,我们定义了一个序列化函数serialize。在序列化函数中,如果参数obj是People类的实例,则将其转换成字典格式返回;否则抛出一个类型错误。
接下来,我们创建类对象p,并使用json.dumps方法将其序列化,设置dumps方法的default参数为serialize函数,使其能够序列化自定义类对象。
反序列化类
要将序列化后的JSON格式数据反序列化成类对象,需要定义一个反序列化函数,将字典格式转换成类对象。
def deserialize(d):
if 'name' in d and 'age' in d and 'gender' in d:
return People(d['name'], d['age'], d['gender'])
else:
return d
p_load = json.loads(serialized_p, object_hook=deserialize)
print(type(p_load))
print(p_load.name, p_load.age, p_load.gender)
上述代码中,我们定义了一个反序列化函数deserialize。在反序列化函数中,如果字典d符合类People的属性要求,则通过调用类People的构造函数生成一个类对象;否则直接返回字典d。
接下来,我们使用json.loads方法将序列化后的JSON格式数据反序列化成类对象,设置loads方法的object_hook参数为deserialize函数,使其能够反序列化自定义类对象。
JSONpickle模块
JSONpickle模块是基于pickle模块的,它可以将类对象或实例对象序列化成JSON格式,支持所有的数据类型,包括自定义类对象。使用JSONpickle需要先安装它,可以使用pip install jsonpickle命令进行安装。
在以下示例中,我们继续使用上面定义的类People。
序列化类
使用jsonpickle序列化python类对象,只需要调用jsonpickle.encode方法,并传入要序列化的对象即可。默认情况下,jsonpickle会将序列化后的内容以ASCII编码方式进行编码。
import jsonpickle
p = People('Tom', 20, 'Male')
serialized_p = jsonpickle.encode(p)
print(serialized_p)
上述代码中,我们使用jsonpickle.encode方法将类对象p序列化成JSON格式。
反序列化类
将序列化后的JSON格式数据反序列化成类对象也很简单,只需要使用jsonpickle.decode方法即可。
p_load = jsonpickle.decode(serialized_p)
print(type(p_load))
print(p_load.name, p_load.age, p_load.gender)
上述代码中,我们使用jsonpickle.decode方法将序列化后的数据反序列化成类对象。
结论
本文介绍了三种Python类对象序列化的方法:pickle模块序列化、JSON模块序列化和JSONpickle模块序列化。对于pickle模块和JSON模块的序列化,需要定义相应的序列化、反序列化函数;而JSONpickle模块序列化则支持所有数据类型的序列化和反序列化,是一个非常方便的序列化库。在实际开发中,根据需求选择合适的序列化方法即可。