如何在Python中使用prototbuf映射?

问题描述 投票:0回答:3

给出一个原始定义

message EndpointResult {
    int32 endpoint_id = 1;
    // property id as key
    map<int32, TimeSeries> properties = 2;
}

message TimeSeries {
    repeated TimeEntry value = 2;
}

message TimeEntry {
    int32 time_unit = 1;
    float value = 2;
}

我希望在 EndpointResult 类中填充地图。我尝试了docs中建议的不同方法,但都给我带来了错误。

设置测试班

end_point_rslt = nom.EndpointResult()
end_point_rslt.endpoint_id=0

ts = nom.TimeSeries()
te = ts.value.add()
te.time_unit = 0
te.value = 5.

然后尝试不同的方法:

end_point_rslt.properties[0] = ts

ValueError:不允许直接分配子消息

end_point_rslt.properties[0].submessage_field = ts

AttributeError:不允许分配(协议消息对象中没有字段“submessage_field”)。

end_point_rslt.properties.get_or_create(0)
end_point_rslt.properties[0] = ts

ValueError:不允许直接分配子消息

end_point_rslt.properties.get_or_create(0)
end_point_rslt.properties[0].submessage_field = ts

AttributeError:不允许分配(协议消息对象中没有字段“submessage_field”)。

end_point_rslt.properties = {0 : ts}

属性错误:不允许对协议消息对象中的重复字段“属性”进行赋值。

end_point_rslt.properties.get_or_create(0)
end_point_rslt.properties = {0 : ts}

类型错误:无法设置复合字段

任何有关如何在 python 中使用协议缓冲区映射的示例将不胜感激!

python protocol-buffers grpc
3个回答
11
投票

在查看文档后,我意识到问题是我为字典分配了一个类。

正确的语法是

end_point_rslt = nom.EndpointResult()
end_point_rslt.endpoint_id=0
te = end_point_rslt.properties[0].value.add()
te.time_unit = 0
te.value = 5.

3
投票

使用 Struct

的解决方法

而不是

message EndpointResult {
    int32 endpoint_id = 1;
    // property id as key
    map<int32, TimeSeries> properties = 2;
}

使用

message EndpointResult {
    int32 endpoint_id = 1;
    // property id as key
    google.protobuf.Struct properties = 2;
}

使用

发起消息
properties = google.protobuf.struct_pb2.Struct()
properties[key1]=[TimeEntry(time_unit1, val1), TimeEntry(time_unit2, val2)...]
properties[key2]=[TimeEntry(time_unit3, val3)...]

EndpointResult(
    endpoint_id='1',
    properties=properties
)

我在使用地图时也遇到了很多问题,发现这个解决方案有效


0
投票

这里没有看到有人建议这个。但一种方法是利用 protobuf 的

CopyFrom
(ref)。

示例

end_point_rslt.properties[0].CopyFrom(ts)
© www.soinside.com 2019 - 2024. All rights reserved.