2015-03-19 16 views
6

Tôi muốn trợ giúp lặp lại đệ quy trên tất cả các thuộc tính/đối tượng con chứa trong thông báo bộ đệm giao thức, giả định rằng chúng ta không biết tên của chúng, hoặc có bao nhiêu.Looping over Protocol Buffers thuộc tính trong Python

Như một ví dụ, lấy tập tin .proto sau đây từ các hướng dẫn trên trang web 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; 
} 

và sử dụng nó ...:

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 

Với Person, Làm thế nào để sau đó truy cập vào cả tên của thuộc tính và giá trị của thuộc tính cho mỗi phần tử: person.id, person.name, person.email, person.phone.number, person.phone.type?

Tôi đã thử những điều sau đây, tuy nhiên dường như nó không tái diễn vào person.phone.number hoặc 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 

Tôi đã cố gắng sử dụng obj.DESCRIPTOR.fields_by_name.keys để truy cập các yếu tố phụ, nhưng đây là những cơ quan đại diện chuỗi của các đối tượng phụ, không phải là đối tượng chính mình.

obj.name cung cấp cho tôi thuộc tính của tên, nhưng tôi không chắc chắn cách thực sự nhận giá trị của thuộc tính đó, ví dụ: obj.name có thể cho tôi 'tên', nhưng làm cách nào để có được 'john doe' của nó?

Trả lời

16

Tôi không phải là siêu quen thuộc với protobufs, vì vậy có thể có một cách dễ dàng hơn hoặc api cho loại điều. Tuy nhiên, dưới đây cho thấy một ví dụ về cách bạn có thể lặp/introspect và các trường đối tượng và in chúng ra. Hy vọng rằng đủ để giúp bạn đi đúng hướng ít nhất ...

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) 

mà kết quả đầu ra

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

Cracking, cảm ơn bạn :). –

Các vấn đề liên quan