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

如何在Python中实现支持字符串直接比较的嵌套枚举(Nested Enum)

实现可直接比较的嵌套枚举

要解决你遇到的两个问题(枚举成员直接和字符串比较、嵌套枚举直接访问成员),我们可以通过自定义枚举元类结合str子类枚举的方式来实现,既保留原有便捷的字符串比较特性,又支持嵌套枚举的直接访问。

完整解决方案代码

from enum import Enum, EnumMeta

# 自定义元类:处理嵌套枚举的直接访问
class NestedEnumMeta(EnumMeta):
    def __getattribute__(cls, name):
        attr = super().__getattribute__(name)
        # 如果当前属性是枚举成员,且其值是另一个枚举类,则直接返回该枚举类
        if isinstance(attr, Enum) and isinstance(attr.value, type) and issubclass(attr.value, Enum):
            return attr.value
        return attr

# 基类:继承str和Enum,同时使用自定义元类
class NestedStrEnum(str, Enum, metaclass=NestedEnumMeta):
    pass

# 嵌套的蓝色枚举
class Blues(NestedStrEnum):
    DARKBLUE = 'darkblue'
    LIGHTBLUE = 'lightblue'

# 外层颜色枚举
class Colours(NestedStrEnum):
    RED = 'red'
    BLUE = Blues

测试验证

运行以下代码可以验证效果:

print(Colours.RED == 'red')  # 输出: True
print(Colours.BLUE.DARKBLUE == 'darkblue')  # 输出: True
print(Colours.BLUE.LIGHTBLUE == 'lightblue')  # 输出: True

为什么原来的代码会出问题?

  1. 字符串比较失败:你原来的Colours只继承了Enum,没有继承str,所以Colours.RED是一个纯枚举实例,不是字符串子类,直接和'red'比较时会判断为不同类型,返回False。
  2. 嵌套成员访问报错:Colours.BLUE是Colours的枚举成员,它的value才是Blues枚举类。直接访问Colours.BLUE.DARKBLUE时,Python会尝试在Colours的枚举成员对象上找DARKBLUE属性,自然会触发AttributeError。

方案原理说明

  • NestedStrEnum基类:继承str和Enum,确保所有枚举成员都是字符串子类,保留直接和字符串比较的特性。
  • 自定义元类NestedEnumMeta:重写__getattribute__方法,当访问外层枚举的成员时,如果该成员的值是另一个枚举类,就直接返回这个枚举类,而不是枚举成员实例,这样就能直接通过Colours.BLUE.DARKBLUE访问嵌套枚举的成员。

这个方案既符合你想要的嵌套枚举组织方式,又完全保留了原有便捷的字符串比较特性,结构清晰且易于扩展。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 17:17:37