给定如下的枚举:
class Result(IntEnum):
A = 0
B = 1
C = 3
我希望能够动态创建新的枚举成员,但前提是值在给定范围内.例如,给定:
class Result(IntEnum, valid_range=(4, 10)):
A = 0
B = 1
C = 3
我预计会有以下行为:
-
Result(10)
可以,返回一个枚举实例,其中.value
设置为10. -
Result(0)
会返回Result.A
-
Result(20)
或Result("hello")
会得到ValueError
Why?个
这是针对BACnet标准的,这是一种建筑物管理/暖通空调协议.它大大简化了它定义了一组映射到整数值的标准消息类型(例如:READ
、WRITE
、LIST
).我将它们建模为一个枚举:
class MessageType(IntEnum):
READ = 0
WRITE = 1
LIST = 2
然后按如下方式使用:
@dataclass
class Message:
message_type: MessageType
data: bytes
def decode(raw: bytes) -> Message:
message_type = MessageType(unpack("!H", bytes[:2]))
data = bytes[2:]
return Message(message_type=message_type, data=data)
该协议还允许供应商定义他们自己的消息类型,但将它们限制在特定的值范围内(即在10到20之间).
Options considered:个
- 显式地或动态地将每个值定义为一个附加的枚举属性(即
MessageType.VENDOR_10
),但有效值的数量可以是数百万,其中大多数将不会被使用. - 不要使用枚举,只需使用
int
、intTypeAlias
或仅使用自定义类. - 将
Message
上的类型注释更改为int | MessageType
,并在解码时try 创建MessageType
,捕获ValueError
并分配int.