Protobufメッセージへの文字列によるアクセス

Protobufのメッセージ型に文字列型をキーとしてアクセスする方法


メッセージ例

以下のメッセージ定義を用いて説明していきます。メンバとして繰り返し型のvaluesおよび、内部メッセージ型のwordsを定義しています

syntax = "proto3";

message NestedMessage {
  string name = 1;
  repeated double values = 2;
  message InnerMessage {
    uint32 word_hi = 1;
    uint32 word_lo = 2;
  }
  InnerMessage words = 3;
}

基本データ型へのアクセス

getattr()setattr()でアクセスします

    pm = nested_message_pb2.NestedMessage()

    # 書き込み
    setattr(pm, 'name', 'Dummy NestedMessage')

    # 読み出し
    d = getattr(pm, 'name')

リピート型へのアクセス

getattr() + append() またはextend()

    pm = nested_message_pb2.NestedMessage()

    # リピート型へのアクセス
    getattr(pm, 'values').append(1)
    getattr(pm, 'values').extend([2, 3])

内部メッセージ型へのアクセス

getattr() + setattr()

    pm = nested_message_pb2.NestedMessage()

    # 内部メッセージ型へのアクセス
    setattr(getattr(pm, 'words'), 'word_hi', 1234)
    setattr(getattr(pm, 'words'), 'word_lo', 5678)

リピート型、内部メッセージ型の判定方法

FieldDescriptorcpp_typeおよびlabelで判定します

from google.protobuf.descriptor import FieldDescriptor as fd

    pm = nested_message_pb2.NestedMessage()

    # フィールドがメッセージ型かどうかの判定方法
    assert pm.DESCRIPTOR.fields_by_name['words'].cpp_type == fd.CPPTYPE_MESSAGE

    # フィールドがリピート型かどうかの判定方法
    assert pm.DESCRIPTOR.fields_by_name['values'].label == fd.LABEL_REPEATED

おすすめ