当我们需要在Python中进行数据传输时,常用的数据格式是JSON(JavaScript Object Notation)。由于JSON文本格式较为简洁,易于阅读和编写,因此在网络上广泛应用。但在某些应用场景下,JSON却存在着一些限制,如传输大量二进制数据时,每个字节需要被转义为字符串,这会大大增加传输数据的大小,降低传输效率。因此,一些开发者选择使用Protocol Buffers作为数据格式。在以下教程中,我们将会学习如何使用Python中的protobuf和json之间进行互相转换。
protobuf与json格式介绍
protobuf格式
protobuf是Protocol Buffers的简称。它是由Google公司开发的一种数据序列化协议,可用于序列化结构化数据,支持多种编程语言。protobuf定义了消息格式和消息之间的交互规则。相比JSON格式,protobuf格式具可读性好,数据传输体积小,传输速度快,可扩展性强等优点。
JSON格式
JSON是JavaScript对象标记语言,是一种轻量级的数据交换格式。JSON格式具有简单明了、易于人阅读、语法简洁等优点,常用于网络传输数据。
protobuf和json互相转换的应用处理方法
序列化为protobuf格式
定义protobuf数据结构通常需要.proto文件,语法类似于C++语言,定义了消息的类型、字段中包含的数据类型和名称、消息按哪个顺序进行编码等元数据信息。在Python中,我们需要使用Google发布的Python语言的proto3库将Python对象序列化为protobuf消息。
示例1:定义protobuf数据结构
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
repeated string emails = 3;
}
在示例1中,我们定义了一个Person类型,包含姓名、年龄和电子邮件三个字段。
示例2:Python对象序列化为protobuf消息
import person_pb2
# 新建person对象
person = person_pb2.Person()
person.name = 'Tom'
person.age = 20
person.emails.extend(['mymail@example.com', 'yourmail@example.com'])
# 序列化为protobuf消息
serialized_message = person.SerializeToString()
在示例2中,我们使用Python的person_pb2模块中定义好的Person类来新建一个person对象,并设置对象的属性。最后,我们使用SerializeToString()方法将对象序列化为protobuf消息,可以在网络中进行传输。
反序列化为Python对象
当我们收到protobuf消息时,需要将其反序列化为Python对象,再进行后续的处理。
示例3:从protobuf消息反序列化为Python对象
import person_pb2
# 读取protobuf消息
serialized_message = b'\n\tTom\x10\x14\x1a\x12mymail@example.com\x1a\x14yourmail@example.com'
person = person_pb2.Person()
person.ParseFromString(serialized_message)
# 对象反序列化后,可以直接访问对象属性
print(f'Name: {person.name}')
print(f'Age: {person.age}')
print(f'Emails: {person.emails}')
在示例3中,我们将收到的protobuf消息反序列化为Python对象。使用Person类的ParseFromString()方法,解析收到的消息并将其赋值给person对象。这时,person对象的属性已经设置完成,我们可以直接访问它们的值,并进行后续的处理。
序列化为JSON格式
由于Python内置的JSON模块不支持直接序列化protobuf消息,因此我们需要将protobuf消息先转换为字典,再使用JSON模块将字典序列化为JSON格式。
示例4:将protobuf消息转换为字典,并序列化到JSON格式
import json
import person_pb2
# 新建person对象
person = person_pb2.Person()
person.name = 'Tom'
person.age = 20
person.emails.extend(['mymail@example.com', 'yourmail@example.com'])
# 将protobuf消息转换为字典,并序列化到JSON格式
person_dict = {
'name': person.name,
'age': person.age,
'emails': list(person.emails),
}
json_str = json.dumps(person_dict)
# 查看JSON格式的字符串
print(json_str)
在示例4中,我们先新建一个person对象,并设置它的属性。接着,我们将person对象转换为字典,再使用Python内置的json模块的dumps()方法将字典序列化为JSON格式。最后,我们可以输出得到的JSON格式字符串。
反序列化为Python对象
对于从JSON格式得到的数据,我们需要将其转换为Python对象进行处理。由于Python接收到的JSON数据不包含字段类型信息,因此我们需要为其他人编写消息类型生成的.protobuf数据文件生成新的Python类,以便反序列化JSON数据。
示例5:从JSON格式反序列化为Python对象
import json
import person_pb2
# 读取JSON格式字符串
json_str = '{"name": "Tom", "age": 20, "emails": ["mymail@example.com", "yourmail@example.com"]}'
person_dict = json.loads(json_str)
# 将字典转换为person对象
person = person_pb2.Person()
person.name = person_dict['name']
person.age = person_dict['age']
person.emails.extend(person_dict['emails'])
# 查看person对象的属性
print(f'Name: {person.name}')
print(f'Age: {person.age}')
print(f'Emails: {person.emails}')
在示例5中,我们将JSON格式的字符串读取到person_dict字典中,并将其转换为person对象。person对象的属性设置完成后,我们可以直接访问它们的值,并进行后续的处理。
结论
在网络传输或数据持久化中,我们需要选择适合应用场景的数据格式。对于一些大量二进制数据的传输场景,protobuf格式相比于JSON格式则具有较为明显的优势。我们通过上述示例,学习了在Python中protobuf和json之间进行互相转换的方法,这对我们处理数据和进行协议设计具有较高的参考价值。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python中protobuf和json互相转换应用处理方法 - Python技术站