phone.proto文件如下:
syntax = 'proto3';
import "google/protobuf/any.proto";
package main;
message User{
int32 index = 1;
string name = 2;
repeated Phone content = 3;
google.protobuf.Any Value = 4;
}
message Phone{
string phoneType = 1;
int32 number = 2;
}
enum PhoneType{
Telephone = 0;
Home = 1;
Work = 2;
}
message Remark{
string note = 1;
}
说明:例子为一种电话簿的传输协议
message User 用户信息,为总信息
message Phone 电话号码信息
enum PhoneType 枚举电话号码类型
message Remark 备注
1、CMD下使用命令将 proto 文件转换成 python 模块。
protoc .\phone.proto --python_out=.\
2、生成了一个名为 phone_pb2.py 文件
3、生成方式与解析解析如下
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author: Richard
# 导入phone_pb2模块
import phone_pb2
# 创建user实例
user = phone_pb2.User()
# 填入user信息
user.index = 1
user.name = "User1"
# 1、当 message 嵌套写入数据时,使用 add()
phone = user.content.add()
pt = phone_pb2.PhoneType
# 2、enum 字段类型,使用 .Name(<int>)类型进行查看
# print(pt.Name(0))
phone.phoneType = pt.Name(0)
phone.number = 10000
# 3、repeated 字段类型,查看转义源码 default_value=[] 可知为 list 类型,可使用 append()添加字段
user.content.append(phone)
info = phone_pb2.Remark()
info.note = "中国电信"
# info.note = "中国电信".encode('raw_unicode_escape')
# info.note = "中国电信".encode('unicode-escape')
mark = user.Value
# 4、Any 字段类型类似于泛型,使用 .Pack() 进行添加,使用 .Unpack() 类型进行解析
mark.Pack(info)
# 生成二进制文件
out_b = user.SerializeToString()
print(out_b)
解析二进制文件
user_out = phone_pb2.User()
# 解析二进制文件
user_out.ParseFromString(out_b)
print(user_out)
解析 Any 类型下的中文:
- note 信息存在于Value.value下,由于二进制流里混合了 UTF-8 和非 UTF-8 信息,解析比较困难,目前只找到这种解决办法。有好的方法也可以交流。
print(user_out.Value.value.decode('utf-8').replace("",'').strip())
# 中国电信