我正在编写一个接收protobufs的Python脚本,将它们转换为json对象,并将它们推送到另一个服务。我使用json.loads(MessageToJson(protobuf))
将protobuf转换为python字典对象。后来我用json.dumps(dictionary)
将它转换回json。
我有一个带有可选枚举字段的proto,例如:
enum C_TYPE
{
AB = 0;
BC = 1;
CD = 2;
}
当我收到一个带有指定为BC
的字段的原型时,一切都按预期工作。当我收到一个带有指定AB
字段的原型时,该字段被忽略 - 它不会出现在python字典或后续的json转储中。我找到的解决方法是使用json.loads(MessageToJson(protobuf, including_default_value_fields=True))
,但这将为所有缺少的字段创建默认值,而不仅仅是具有0
枚举的字段。这意味着枚举0
的字段缺失 - 但它不是!
当枚举字段设置为0
时,检索枚举字段值的正确方法是什么?
答案 0 :(得分:2)
没有正确的方法,我错误地定义了我的protobufs。对于枚举字段,第一个值是的默认值。这意味着如果protobuf在没有设置值的情况下通过,则会将其设置为默认值,并在转换为json时被忽略(除非您要保留所有默认值。)
因此,建议使用普通名称作为默认值,以便能够正确区分何时设置。即我应该将我的protobuf定义为:
enum C_TYPE
{
NONE = 0;
AB = 1;
BC = 2;
CD = 3;
}
来自Protobuf Documentation on Optional Fields And Default Values:
对于枚举,默认值是枚举中列出的第一个值 类型定义。这意味着在添加值时必须小心 枚举值列表的开头。
这是按预期工作的。 proto3零值在中省略 JSON格式也是如此。零值应该是"一次性"价值:它 如果序列化消息的发送者设置了,您将看到的内容 字段为无效或无法识别的值。
答案 1 :(得分:0)
在 C++ 的 protobuf 中,可以添加一个选项来始终打印原始字段。 在 MessageToJson 转换中添加此选项会使 protobuf 添加参数,即使它们设置为零。
google::protobuf::util::JsonPrintOptions options;
options.always_print_primitive_fields = true;