查看 Python 模块和示例 protobuf 定义 here
给定示例 protobuf 定义:
syntax = "proto3";
message Data1 {
double a = 1;
float b = 2;
int32 c = 3;
int64 d = 4;
bool e = 5;
string f = 6;
bytes g = 7;
}
message Data2 {
Data1 a = 1;
map<string, Data1> b = 2;
map<string, int32> c = 3;
repeated Data1 d = 4;
repeated int32 e = 5;
}
产生以下内容:
>>> import test_pb2
>>> msgs = module_msgs(test_pb2)
>>> print(msgs)
{'Data1': Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES'),
'Data2': Data2(a=Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES'), b=Map(key='TYPE_STRING', value=Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES')), c=Map(key='TYPE_STRING', value='TYPE_INT32'), d=Repeated(value=Data1(a='TYPE_DOUBLE', b='TYPE_FLOAT', c='TYPE_INT32', d='TYPE_INT64', e='TYPE_BOOL', f='TYPE_STRING', g='TYPE_BYTES')), e=Repeated(value='TYPE_INT32')),
}
module_msgs 函数将 protobuf 模块作为输入,并以消息名称作为键返回 dict,并生成 namedtuple 对象作为值。这是要使用的“顶级”功能。
我使用nametuple 类型来表示 protobuf 消息。您可以通过 _fields 属性遍历它们的字段。事后看来,typing.NamedTuple 或 collections.OrderedDict 可能更合适。
我创建了两个特殊的namedtuples:Map 和 Repeated。您可以使用isinstance 检查确定字段是映射还是重复。
TYPE_* 字符串对应于 protobuf 字段类型。因此,protobuf 消息 namedtuple 的字段值可以是字符串(对应于 protobuf 类型)、Repeated 或 Map 对象,或另一个 namedtuple 对象。
这还没有用其他 protobuf 功能测试过,例如默认值、Any、Oneof 等。
有关更多用法和测试,请参阅要点中的__main__。