如标题所示,我有一个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] 删除。
我来说两句