在Python中循环协议缓冲区属性 [英] Looping over Protocol Buffers attributes in 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.id
,person.name
,person.email
,person.phone.number
,person.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.number
或person.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屋!