簡體   English   中英

如何獲取protobuf消息中定義的變量類型?

[英]How to get the type of a variable defined in a protobuf message?

我正在嘗試使用 Python 從 protobuf 文件到 Objective-C 類進行一些“轉換”。 例如,給定 protobuf 消息:

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

我想把它翻譯成一個 objc 類:

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int ID;
@property (nonatomic, copy) NSString *email; 
@end

關鍵點是獲取每個屬性的名稱和類型。 比如protobuf消息中的'optional string email',它的名字是'email',類型是'string',所以在objective-c中應該是NSString *email。 我按照官方教程,寫了一個addressbook.proto和教程一樣,編譯了。 然后我寫了我的python代碼:

import addressbook_pb2 as addressbook

p = addressbook.Person()
all_fields = p.DESCRIPTOR.fields_by_name
# print "all fields: %s" %all_fields
field_keys = all_fields.keys()
# print "all keys: %s" %field_keys

for key in field_keys:
    one_field = all_fields[key]
    print one_field.label

這只是給了我:

1
2
3
2

所以我想 label 不是我需要的,而 field_keys 只是我期望的名稱列表。 我嘗試了一些其他詞,並在網上進行了一些搜索,但沒有找到正確的答案。

如果沒有辦法獲取類型,我還有一個想法,就是用純“Pythonic”的方式讀取和分析protobuf源文件的每一行,但如果沒有必要,我真的不想這樣做。

有誰能夠幫助我?

FieldDescriptor類有一個message_type成員,如果是復合字段,則是該字段中包含的消息類型的描述符。 否則,這是無。

將此與遍歷DESCRIPTORS字典相結合意味着您可以獲得復合和非復合(原始)字段的名稱類型

import addressbook_pb2 as addressbook
DESCRIPTORS = addressbook.Person.DESCRIPTOR.fields_by_name

for (field_name, field_descriptor) in DESCRIPTORS.items():

    if field_descriptor.message_type:
        # Composite field
        print(field_name, field_descriptor.message_type.name)
    else:
        # Raw type
        print(field_name, field_descriptor.type)
        # TYPE_DOUBLE
        # TYPE_FLOAT 
        # TYPE_INT64 
        # TYPE_UINT64
        # TYPE_INT32 
        # TYPE_FIXED64
        # TYPE_FIXED32
        # TYPE_BOOL  
        # TYPE_STRING
        # TYPE_GROUP
        # TYPE_MESSAGE
        # TYPE_BYTES
        # TYPE_UINT32
        # TYPE_ENUM
        # TYPE_SFIXED32
        # TYPE_SFIXED64
        # TYPE_SINT32
        # TYPE_SINT64
        # MAX_TYPE

原始類型是類屬性; https://github.com/protocolbuffers/protobuf/blob/master/python/google/protobuf/descriptor.py

感謝 Marc 的回答,我想出了一些解決方案。 這只是一個想法,但這對我來說是一個巨大的進步。

蟒蛇代碼:

import addressbook_pb2 as addressbook

typeDict = {"1":"CGFloat", "2":"CGFloat", "3":"NSInteger", "4":"NSUinteger", "5":"NSInteger", "8":"BOOL", "9":"NSString", "13":"NSUinteger", "17":"NSInteger", "18":"NSInteger"}

attrDict = {"CGFloat":"assign", "NSInteger":"assign", "NSUinteger":"assign", "BOOL":"assign", "NSString":"copy"}

p = addressbook.Person()
all_fields = p.DESCRIPTOR.fields_by_name
field_keys = all_fields.keys()
for key in field_keys:
    one_field = all_fields[key]
    typeNumStr = str(one_field.type)
    className = typeDict.get(typeNumStr, "NSObject")
    attrStr = attrDict.get(className, "retain")
    propertyStr = "@property (nonatomic, %s) %s *%s" %(attrStr, className, key)
    print propertyStr

對於地址簿示例,它打印:

@property (nonatomic, copy) NSString *email
@property (nonatomic, copy) NSString *name
@property (nonatomic, retain) NSObject *phone
@property (nonatomic, assign) NSInteger *id

不是最終的解決方案,但它意味着很多。 謝謝你,馬克!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM