protocol protobuf google python attributes buffer protocols elements

protobuf - Looping sobre los atributos de Buffers de protocolo en Python



google buffer protocol (1)

No estoy muy familiarizado con los protobufs, por lo que puede haber una manera más fácil o api para este tipo de cosas. Sin embargo, a continuación se muestra un ejemplo de cómo se pueden iterar / introspectar y objetos campos e imprimirlos. Con suerte lo suficiente para que vayas en la dirección correcta, al menos ...

import addressbook_pb2 as addressbook person = addressbook.Person(id=1234, name="John Doe", email="[email protected]") 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)

que salidas

tutorial.Person.name: John Doe tutorial.Person.id: 1234 tutorial.Person.email: [email protected] tutorial.Person.PhoneNumber.number: 1234567890 tutorial.Person.PhoneNumber.type: HOME

Me gustaría ayudar con el bucle recursivo sobre todos los atributos / subobjetos contenidos en un mensaje de búfer de protocolo, suponiendo que no conocemos su nombre o cuántos hay.

Como ejemplo, tome el siguiente archivo .proto del tutorial en el sitio web de google:

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; }

y para usarlo ...:

person = tutorial.Person() person.id = 1234 person.name = "John Doe" person.email = "[email protected]" phone = person.phone.add() phone.number = "555-4321" phone.type = tutorial.Person.HOME

Person dada, ¿cómo puedo acceder al nombre del atributo y su valor para cada elemento: person.name , person.email , person.phone.number , person.phone.type , person.phone.type ?

He intentado lo siguiente, sin embargo, parece que no se repite en person.phone.number o 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

He intentado usar obj.DESCRIPTOR.fields_by_name.keys para acceder a los elementos secundarios, pero estas son las representaciones de cadena de los objetos secundarios, no los objetos mismos.

obj.name me da el atributo del nombre, pero no estoy seguro de cómo obtener realmente el valor de ese atributo, por ejemplo, obj.name puede darme ''nombre'', pero ¿cómo obtengo ''john doe'' de él?