在 Python 中循环遍历 Protobuf 枚举值

3

目前我在Python 3.7中使用protobuff3对数据包进行序列化并通过网络传输。重构之前,我使用的是常规枚举,但现在我已经转向使用protobuff枚举。然而,我没有找到一种方法来检查值是否在枚举中。在普通的Python中,我会这样做:if item in enum:。最好的方法是什么?

我的protobuff文件:

syntax = "proto3";

package vlcTogether;

message defaultPacket {
    Commands command = 1;
    string param = 2;

    enum Commands {
        ERROR = 0;
        JOIN = 1;
        QUIT = 2;
        VLC_COMMAND = 3;
        SERVER_INFO = 4;
    }
}
1个回答

2
<最初的回答> google.protobuf.pyext.cpp_message.GeneratedProtocolMessageTypedefaultPacket 属性具有一个 Commands 属性。
该属性是 google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper 类的实例,具有以下方法: NameValueName 方法返回整数在 Enum 中存在时的名称,否则引发 ValueError 异常。 Value 方法返回字符串在 Enum 中存在时的值,否则引发类似的 ValueError 异常。
def valuenum_in_enum(enum_wrapper, valuenum):
    try:
        if enum_wrapper.Name(valuenum):
            return True
    except ValueError:
        return False

def valuename_in_enum(enum_wrapper, valuename):
    try:
        if enum_wrapper.Value(valuename):
            return True
    except ValueError:
        return False 

>>> valuenum_in_enum(defaultPacket.Commands, 2)
True
>>> valuename_in_enum(defaultPacket.Commands, 'QUIT')
True

另一个简单的方法是使用CommandsDESCRIPTOR属性。 它具有返回映射的values_by_numbervalues_by_name属性。 例如,DESCRIPTOR.values_by_number[1]将返回第一个命令的名称。
>>> commands_descriptor = defaultPacket.Commands.DESCRIPTOR

>>> 'QUIT' in commands_descriptor.values_by_name
>>> 2 in commands_descriptor.values_by_number

谢谢,我正在寻找第二个,那正是我所需要的。 - Clément Péau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接