2016-10-24 12 views
1

私はPythonを使ってGoogle ProtoBufを受け取りました。その列挙値の値を文字列表現と比較しようとしています。 thisthisに基づいて、私は必要な情報を得るためにenum_values_by_nameのようなものを使用できるはずです。おそらくそれは、私のいるProtobufは、多くのファイルで定義されているという事実に関連しているPythonで列挙された列挙を探し出すDESCRIPTOR for ProtoBuf

>>> type(my_message) 
<class 'myObjects_pb2.myObject'> 

>>> my_message 
# nID: 53564 
# nAge: 2 
# type: OBJECT_CLASS_SIGN 
# view: OBJECT_VIEW_FRONT 

>>> my_message.type 
# 1 

>>> filter(lambda s: s.startswith('enum'), dir(my_message.DESCRIPTOR)) 
# ['enum_types', 'enum_types_by_name', 'enum_values_by_name'] 

>>> my_message.DESCRIPTOR.enum_types 
# [] 

>>> my_message.DESCRIPTOR.enum_types_by_name 
# {} 

>>> my_message.DESCRIPTOR.enum_values_by_name 
# {}  

、そして私が欲しい列挙型は、私は輸入てるメインファイルで定義されていない。しかし、すべてのenum*関連の属性は空です(ただし、my_messageのデコードに使用されます)?

なぜこれらの空のコレクションを取得していますか(さらに重要なことに)列挙型についての情報を見つけるにはどうすればよいですか?

答えて

1

なぜメッセージのDESCRIPTORには、入力されていない列挙型属性が含まれているのかわかりません。しかし、これには少なくとも2つの解決法があります:

1)列挙型が定義されているファイルの名前を知っていれば、介した名前で列挙型の値:

# This is the root ProtoBuf definition 
from mydir import rootapi_pb2 

# We happen to know that the enums are defined in myenums.proto 
enum_file = rootapi_pb2.myenums__pb2 # NOTE: Extra Underscore! 
enum_value = getattr(enum_file, 'OBJECT_CLASS_SIGN') 

あなたはこのハックに頼るしたくない場合は、しかし、あなたは最終的に列挙型記述子を見つけることができ、そして名前からこれ値、経由:

my_message.DESCRIPTOR.fields_by_name['type'].enum_type.values_by_name['OBJECT_CLASS_SIGN'].number 

これは恐ろしいので、ここでは安全で再利用可能な関数としてラップされます:

def enum_value(msg, field_name, enum_name): 
    """Return the integer for the enum name of a field, 
     or None if the field does not exist, is not an enum, or the 
     enum does not have a value with the supplied name.""" 
    field = msg.DESCRIPTOR.fields_by_name.get(field_name,None) 
    if field and field.enum_type: 
     enum = field.enum_type.values_by_name.get(enum_name,None) 
     return enum and enum.number 

print(enum_value(my_message, 'type', 'OBJECT_CLASS_SIGN')) 
# 1 
+0

_Editorial:Python言語とProtoBuf APIの設計については、情報を取得する正しい方法がしばしば非常に面倒で冗長であり、基本的に目標を達成するための関数を記述する必要があると言われています。 IMHO Pythonコミュニティは、プラグマティズムと利便性を評価していないようです(少なくとも他の類似言語と比較して)。 – Phrogz