如何在python3中获取protobuf的RepeatedCompositeContainer或RepeatedScalarContainer包含的类型?

Posted

技术标签:

【中文标题】如何在python3中获取protobuf的RepeatedCompositeContainer或RepeatedScalarContainer包含的类型?【英文标题】:How to get type contained by protobuf's RepeatedCompositeContainer or RepeatedScalarContainer in python3? 【发布时间】:2019-07-26 14:42:30 【问题描述】:

我正在编写一个 Python 应用程序来序列化和发送 protobuf3 消息。我想制作某种交互式 UI,允许选择一条消息并即时分配它。我有相当多的这些消息,因此我不想为每条消息都创建一个 get 函数,而是创建一个可以处理所有消息的函数。

对于get所有消息字段,我可以简单地获取所有消息的属性并选择那些是它的字段,这很容易。然后,要知道属性是什么类型,我使用type(getattr(my_message, current_field))。现在有问题了。假设这些是我的消息:

message myMess1 
    //some fields


message myMess2 
    string some_string = 1
    repeated myMess1 myMess1Field = 2

现在,分配 some_string 字段没有问题。

type(getattr(myMess2Instance, someStringFieldName)) 返回string,所以我知道用字符串喂它。

但是如何处理重复的 myMess1 字段? type(getattr(MyMess2Instance, myMess1FieldName)) 实际上返回 google.protobuf.pyext._message.RepeatedCompositeContainer,它没有说明其中包含什么类型。我怎样才能得到它?

【问题讨论】:

【参考方案1】:

我有一个类似的 Protobuf 解析问题,这是我所做的“希望它有所帮助”:

假设我们有这个响应消息:

>>> msg
path 

path 
  value: "Arts & Entertainment"

path 
  value: "Comics & Animation"

将其转换为字典:

>>> from google.protobuf.json_format import MessageToDict
>>> d = MessageToDict(msg)
'path': ['', 'Arts & Entertainment', 'Comics & Animation']

将值的字典列表作为字符串加入:

>>> " ".join(d["path"]).strip()
'Arts & Entertainment Comics & Animation'

【讨论】:

【参考方案2】:

这确实让我困惑了一段时间,因为似乎没有生成任何文档。关键是要看到RepeatedCompositeContainer 的行为就像一个列表。您可以迭代内容,在示例中将具有 myMess1 生成的类型。例如:

for myMess1Element in myMess2Instance.myMess1FieldName:
    print(f"myMess1Element.some_field=")
    print(f"myMess1Element.other_field=")

如果您以某种方式提前知道该消息的重复次数,则可以索引特定的消息。例如:

print(f"myMess2Instance.myMess1FieldName[0]")

建议检查长度,因为消息可以重复任意次数(包括零次)。

【讨论】:

以上是关于如何在python3中获取protobuf的RepeatedCompositeContainer或RepeatedScalarContainer包含的类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式获取 gRPC / protobuf 版本?

如何在 ZeroMQ 的 REQ-REP 模式中获取请求者的公共 IP?

如何使用 QTcpSocket 获取 Protobuf 发送的数据 [重复]

如何使用自定义protobuf构建tensorflow 1.13.1?

如何自省 Python 中所有有效的 protobuf 枚举值?

如何使用 Protobuf 做数据交换 | Linux 中国