You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Python Enum接受任意值而不抛出ValueError?

问题场景

我在实现一个接收命令的网络服务,用枚举定义支持的命令,代码如下:

import enum

class Command(enum.Enum):
    ECHO = 0x01
    LOGIN = 0x02
    SEND_FILE = 0x03

def handle_packet(p: bytes):
    command = Command(p[0])
    if command == Command.ECHO:
        print(p[1:])
    elif ...
    elif ...
    else:
        print('Ignoring unknown command', command)

当客户端协议版本比服务器新时,可能会发送枚举中未定义的命令(比如0x04),此时Command(p[0])会抛出ValueError。我希望执行command = Command(0x04)时能正常创建实例,要求command.value = 4,且自动生成类似COMMAND_04的name属性。

解决方案

利用Python标准库enum提供的_missing_钩子方法,自定义一个支持动态生成未知成员的枚举基类:

import enum

class DynamicCommandEnum(enum.Enum):
    @classmethod
    def _missing_(cls, value):
        # 处理未定义的枚举值
        member = cls._create_pseudo_member_(value)
        # 按格式生成name属性,采用两位大写十六进制格式
        member.name = f"COMMAND_{value:02X}"
        return member

# 继承自定义基类定义命令枚举
class Command(DynamicCommandEnum):
    ECHO = 0x01
    LOGIN = 0x02
    SEND_FILE = 0x03
测试验证
# 测试已知命令
echo_cmd = Command(0x01)
print(echo_cmd.name)  # 输出 ECHO
print(echo_cmd.value) # 输出 1

# 测试未知命令
unknown_cmd = Command(0x04)
print(unknown_cmd.name)  # 输出 COMMAND_04
print(unknown_cmd.value) # 输出 4

# 在处理函数中使用
def handle_packet(p: bytes):
    command = Command(p[0])
    if command == Command.ECHO:
        print(p[1:])
    elif command == Command.LOGIN:
        # 处理登录逻辑
        pass
    elif command == Command.SEND_FILE:
        # 处理文件发送逻辑
        pass
    else:
        print(f'Ignoring unknown command: {command.name} (0x{command.value:02X})')
说明
  • _missing_是Enum类的内置钩子,当传入的value没有匹配的枚举成员时会自动调用
  • _create_pseudo_member_用于创建临时枚举成员实例,确保其行为和正常枚举成员一致
  • 可按需调整name的生成格式,比如改成十进制格式只需把f"COMMAND_{value:02X}"改为f"COMMAND_{value}"

内容的提问来源于stack exchange,提问作者rgov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:22:16