【问题标题】:Python: print protobuf spec (fields, types)Python:打印 protobuf 规范(字段、类型)
【发布时间】:2018-06-12 08:25:55
【问题描述】:

如果您有一个对应于module_name_pb2.py 文件的模块对象,或者访问.proto 文件本身,有没有办法以漂亮的方式打印规范本身? JSON?我想显示字段和类型。

希望打印一个实例,例如Print human friendly Protobuf message

给定一些 protobuf 消息格式(在 .proto 文件中定义),例如:

message XYData {
    float x = 1;
    float y = 2;
}

我正在寻找类似的东西:

{
   "name" : "XYData",
   "fields" : [
                {"name" : "x", "type" : "float"},
                {"name" : "y", "type" : "float"}
              ]
}

如果能够列出 .proto 文件中定义的所有消息也很好。

编辑:也许是这样,但在 Python 中:https://github.com/devongovett/protobuf-jsonschema

【问题讨论】:

    标签: python protocol-buffers


    【解决方案1】:

    查看 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.NamedTuplecollections.OrderedDict 可能更合适。

    我创建了两个特殊的namedtuples:MapRepeated。您可以使用isinstance 检查确定字段是映射还是重复。

    TYPE_* 字符串对应于 protobuf 字段类型。因此,protobuf 消息 namedtuple 的字段值可以是字符串(对应于 protobuf 类型)、RepeatedMap 对象,或另一个 namedtuple 对象。

    这还没有用其他 protobuf 功能测试过,例如默认值、Any、Oneof 等。

    有关更多用法和测试,请参阅要点中的__main__

    【讨论】:

    • 谢谢!我会奖励你的辛勤工作。这可能是类似于我上面链接的节点模块的模块的开始。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2022-01-26
    • 1970-01-01
    • 2023-01-09
    • 2014-06-28
    • 1970-01-01
    • 2014-04-26
    相关资源
    最近更新 更多