在Python中循环协议缓冲区属性 [英] Looping over Protocol Buffers attributes in Python

查看:91
本文介绍了在Python中循环协议缓冲区属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想帮助递归循环协议缓冲区消息中包含的所有属性/子对象,假设我们不知道它们的名称或名称.

I would like help with recursively looping over all attributes/sub objects contained in a protocol buffers message, assuming that we do not know the names of them, or how many there are.

作为示例,请从Google网站上的教程中获取以下.proto文件:

As an example, take the following .proto file from the tutorial on the google website:

  message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

并使用它...:

person = tutorial.Person()
person.id = 1234
person.name = "John Doe"
person.email = "jdoe@example.com"
phone = person.phone.add()
phone.number = "555-4321"
phone.type = tutorial.Person.HOME

给出Person,然后如何访问属性名称和每个元素的值:person.idperson.nameperson.emailperson.phone.numberperson.phone.type?

Given Person, How do I then access both the name of the attribute and its value for each element: person.id, person.name, person.email, person.phone.number, person.phone.type?

我尝试了以下方法,但是似乎没有出现在person.phone.numberperson.phone.type中.

I have tried the following, however it doesn't seem to recurs into person.phone.number or person.phone.type.

object_of_interest = Person

while( hasattr(object_of_interest, "_fields") ):
  for obj in object_of_interest._fields:
    # Do_something_with_object(obj) # eg print obj.name
    object_of_interest = obj

我尝试使用obj.DESCRIPTOR.fields_by_name.keys访问子元素,但这是子对象的字符串表示形式,而不是对象本身.

I have tried using obj.DESCRIPTOR.fields_by_name.keys to access the sub elements, but these are the string representations of the sub objects, not the objects themselves.

obj.name为我提供了名称的属性,但是我不确定如何实际获取该属性的值,例如obj.name可能给我提供名称",但是我如何从中获得"john doe"它吗?

obj.name gives me the attribute of the name, but im not sure how to actually get the value of that attribute, eg obj.name may give me 'name', but how do i get 'john doe' out of it?

推荐答案

我对protobufs不太熟悉,因此很可能有一种更简单的方法或api.但是,下面显示了如何迭代/检查和对象字段并打印出来的示例.希望足以让您至少朝正确的方向前进...

I'm not super familiar with protobufs, so there may well be an easier way or api for this kind of thing. However, below shows an example of how you could iterate/introspect and objects fields and print them out. Hopefully enough to get you going in the right direction at least...

import addressbook_pb2 as addressbook

person = addressbook.Person(id=1234, name="John Doe", email="foo@example.com")
person.phone.add(number="1234567890")


def dump_object(obj):
    for descriptor in obj.DESCRIPTOR.fields:
        value = getattr(obj, descriptor.name)
        if descriptor.type == descriptor.TYPE_MESSAGE:
            if descriptor.label == descriptor.LABEL_REPEATED:
                map(dump_object, value)
            else:
                dump_object(value)
        elif descriptor.type == descriptor.TYPE_ENUM:
            enum_name = descriptor.enum_type.values[value].name
            print "%s: %s" % (descriptor.full_name, enum_name)
        else:
            print "%s: %s" % (descriptor.full_name, value)

dump_object(person)

输出

tutorial.Person.name: John Doe
tutorial.Person.id: 1234
tutorial.Person.email: foo@example.com
tutorial.Person.PhoneNumber.number: 1234567890
tutorial.Person.PhoneNumber.type: HOME

这篇关于在Python中循环协议缓冲区属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆