Python中应用protobuf的示例详解
Protobuf是一种轻量级,高性能,语言无关的序列化框架,用于数据交换和存储。本文将介绍如何在Python中使用protobuf。
安装protobuf
在使用protobuf之前,需要先安装protobuf库:
pip install protobuf
编写proto文件
protobuf使用.proto文件定义交换的消息格式。例如,以下是定义一个简单消息格式的.proto文件的示例:
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
}
上述.proto文件定义了一个消息格式,名为Person,包含两个字段:name和age。其中,name的类型为字符串,字段编号为1;age的类型为32位整型数,字段编号为2。
生成Python代码
使用protoc命令可以将.proto文件编译为各种编程语言的代码。例如,以下命令将生成Python代码:
protoc --python_out=. person.proto
编译后将生成person_pb2.py文件,其中包含Person消息的Python类。
序列化和反序列化
在Python中使用protobuf,可以通过Person类序列化和反序列化消息。以下是示例代码:
import person_pb2
# 创建Person实例
person = person_pb2.Person()
person.name = 'Alice'
person.age = 20
# 将Person序列化为字节串
bytes = person.SerializeToString()
# 将字节串反序列化为Person实例
new_person = person_pb2.Person()
new_person.ParseFromString(bytes)
# 打印反序列化后的Person实例
print(new_person)
上述代码中,首先创建一个Person实例,然后将其序列化为字节串。接着,通过ParseFromString方法将字节串反序列化为Person实例,最后将反序列化后的Person实例打印出来。
示例1:嵌套消息
除了简单的字段,protobuf还支持嵌套消息的定义。以下是一个示例的.proto文件:
syntax = "proto3";
message Phone {
string number = 1;
int32 type = 2;
}
message Person {
string name = 1;
int32 age = 2;
repeated Phone phones = 3;
}
.phone表示电话号码,.person表示人名,其中.phone信息还嵌套在了.person信息里。以下是该.proto文件编译生成的Python代码:
# Phone类定义
class Phone(proto.Message):
number = proto.Field(proto.STRING, number=1)
type = proto.Field(proto.INT32, number=2)
# Person类定义
class Person(proto.Message):
name = proto.Field(proto.STRING, number=1)
age = proto.Field(proto.INT32, number=2)
phones = proto.RepeatedField(Phone, number=3)
上述代码中,Proto文件中定义了嵌套的消息结构,生成的Python代码中使用嵌套的Python类表示这个结构。
以下是创建和序列化一个包含phone信息的Person实例的示例代码:
import person_pb2
# 创建Person实例
person = person_pb2.Person()
person.name = 'Bob'
person.age = 30
# 添加Phone信息
phone = person.phones.add()
phone.number = '123456789'
phone.type = 1
# 将Person实例序列化为字节串
bytes = person.SerializeToString()
# 将字节串反序列化为Person实例
new_person = person_pb2.Person()
new_person.ParseFromString(bytes)
# 打印反序列化后的Person实例
print(new_person)
上述示例中,首先创建一个Person实例,然后添加一个Phone信息到phones中,最后将Person实例序列化为字节串,再反序列化为新的Person实例,并将其打印出来。
示例2:使用Python字典构建消息
在实际使用中,有时需要根据现有信息创建一个Protobuf消息对象。可以使用Python字典来构建一个消息。以下是一个使用字典构建消息的示例:
import person_pb2
person_dict = {
'name': 'Tom',
'age': 40,
'phones': [
{'number': '987654321', 'type': 2},
{'number': '012345678', 'type': 1},
]
}
# 使用字典构建Person实例
person = person_pb2.Person()
person.ParseFromDict(person_dict)
# 将Person实例序列化为字节串
bytes = person.SerializeToString()
# 将字节串反序列化为Person实例
new_person = person_pb2.Person()
new_person.ParseFromString(bytes)
# 打印反序列化后的Person实例
print(new_person)
上述示例中,首先创建一个字典person_dict,包含了Person实例的各个字段信息和Phone信息。然后使用ParseFromDict方法将字典转换为Person实例,最后将Person实例序列化为字节串并反序列化为新的Person实例。