如何序列化Protobuf中嵌套消息中的默认值

马尔夫

如标题所示,我有一个protobuf消息,里面有另一个消息,如下所示:

syntax = "proto3";

message Message
{
    message SubMessage {
        int32 number = 1;
    }

    SubMessage subMessage = 1;
}

example.json是空的(这意味着到处都是默认值):

{
}

在我的python脚本中,我读到以下消息:

with open("example.json", "r") as FH:
    exampleJSON = FH.read()

example_message = example.Message()
google.protobuf.json_format.Parse(exampleJSON, example_message)

当我检查example_message.subMessage.number的值0是正确的。

现在,我想将其转换为所有值都存在的dict-甚至是默认值。对于转换,我使用方法google.protobuf.json_format.MessageToDict()但是,您可能知道,MessageToDict()如果没有我告诉默认值,它不会序列化默认值(就像这个问题:Protobuf不会序列化默认值)。因此,我将参数添加including_default_value_fields=True到的调用中MessageToDict()

protobuf.MessageToDict(example_message, including_default_value_fields=True)

返回:

{}

而不是我的预期:

{'subMessage': {'number': 0}}

protobuf代码中的注释(可在以下位置找到:https : //github.com/protocolbuffers/protobuf/blob/master/python/google/protobuf/json_format.py)确认此行为:

included_default_value_fields:如果为True,则将始终序列化单数原始字段,重复字段和映射字段。如果为False,则仅序列化非空字段。单个消息字段和一个字段不受此选项的影响。

所以,我能做些什么来得到一个字典所有,即使他们是嵌套的消息内的默认值值?


有趣的是,当我example.json看起来像这样:

{
    "subMessage" : {
        "number" : 0
    }
}

我得到了预期的输出。但是我不能确保example.json将所有值都写出来,因此这不是一个选择。

马尔夫

基于Python中“协议缓冲区循环”属性的答案,我创建了一个自定义MessageToDict函数:

def MessageToDict(message):
    messageDict = {}

    for descriptor in message.DESCRIPTOR.fields:
        key = descriptor.name
        value = getattr(message, descriptor.name)

        if descriptor.label == descriptor.LABEL_REPEATED:
            messageList = []

            for subMessage in value:
                if descriptor.type == descriptor.TYPE_MESSAGE:
                    messageList.append(MessageToDict(subMessage))
                else:
                    messageList.append(subMessage)

            messageDict[key] = messageList
        else:
            if descriptor.type == descriptor.TYPE_MESSAGE:
                messageDict[key] = MessageToDict(value)
            else:
                messageDict[key] = value

    return messageDict

给定从空读取的消息,example.json此函数返回:

{'subMessage': {'number': 0}}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Protobuf不会序列化默认值

如何在json可序列化中为对象设置默认值?

如何在序列化器中设置默认值?

如何向嵌套序列化程序添加默认值?

如何序列化protobuf文件中的图和值?

如何不序列化默认值

在Java中序列化多个protobuf消息,并在Python中反序列化它们

如何反序列化prpBytes(描述中的链接src)(ProposalResponsePayload protobuf消息)到对象原始

JSON序列化-设置int类型的默认值

如何为 Jackson 反序列化指定默认值

我如何使杰克逊不使用默认值序列化图元

如何在反序列化的对象中保留field的默认值?

序列化null或默认值时如何避免生成JSON?

如何使用模式 id 序列化 protobuf 消息

如何在Actix actor中反序列化消息?

如何反序列化嵌套数组中的字段

如何序列化嵌套在类中的实例列表?

如何使用ScalaPB对使用'oneof'的protobuf消息进行序列化/反序列化?

动态更改序列化的protobuf消息?

在DRF中序列化嵌套对象

如何在序列化器中获取序列化器字段值

ServiceStack-如何反序列化DateTime,每个请求可以采用多种格式,而不会覆盖全局默认值

支持嵌套类型中自定义类的默认序列化

如何在RetrieveUpdateDestroyAPIView中更改序列化数据的值

如何只显示Django序列化器中的值?

ProtoBuf 字段中的集合的 Kryo 序列化问题

ProtoBuf在WebApi HttpResponseMessage中序列化异常

在Python中阅读StanfordNLP输出的Protobuf序列化

无法在python中反序列化protobuf字节字段