python - 查找 ProtoBuf 的 Python DESCRIPTOR 中列出的枚举

标签 python python-3.x protocol-buffers

我收到了使用 Python 的 Google ProtoBuf,并尝试将枚举的值与其字符串表示形式进行比较。基于thisthis我应该能够使用 enum_values_by_name 之类的东西来获取我需要的信息。但是,所有与 enum* 相关的属性都是空的:

>>> 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
# {}    

也许这与我的protobuf在许多文件中定义,而我想要的枚举没有在我导入的主文件中定义(但用于解码my_message)有关>)?

为什么我会得到这些空集合以及(更重要的是)如何查找有关枚举的信息?

最佳答案

我不知道为什么消息的 DESCRIPTOR 包含未填充的枚举属性。 (这对我来说似乎是一个错误。)但是,(至少)有两种解决方案:

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

关于python - 查找 ProtoBuf 的 Python DESCRIPTOR 中列出的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40226049/

相关文章:

python - 像 FourWaySplitter 但不同

python - 为什么没有像主应用程序那样将自定义 url 转换器添加到蓝图的选项?

c++ - 如何将在依赖项 CMake 项目中创建的 Protobuf 生成的 .h 文件正确导入父 CMake 项目?

python - 如何使用python从docx文件中提取超链接中的url

python - 在 Python 函数中使用参数

python - 为什么运行这个 python 脚本会占用我所有的磁盘空间?

django - 如何在sqlite3中正确导入和配置.csv表

python 3 https 发帖很慢

java - Maven ArtifactNotFoundException 故障排除

java - 自定义 mapstruct 以忽略 protobuff 字段