Python Loop over Protocol Attributes

I would like to help with a recursive loop over all the attributes / auxiliary objects contained in the protocol buffer message, assuming that we do not know their names or their number.

As an example, take the following .proto file from a tutorial on 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; } 

and use it ...:

 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 

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

I tried the following, however, it doesn't seem to repeat in 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 

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

obj.name gives me a name attribute, but I'm not sure how to actually get the value of this attribute, for example, obj.name can give me a "name", but how can I get "john doe" from this?

+6
source share
1 answer

I am not very familiar with protobufs, so there might be an easier way or api for this kind of thing. However, the following is an example of how you could iterate / introspect and objects and print them. Hope you go 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) 

which outputs

 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 
+16
source

Source: https://habr.com/ru/post/984013/


All Articles