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

如何创建带层级结构的Enum枚举类型?最佳方案探讨

带层级结构的Enum枚举类型实现方案

问题背景

希望创建带层级的Enum,让子部门的员工枚举既属于自身类型,又能被统一识别为总员工枚举类型。例如:

定义部门枚举:

from enum import Enum

class ProductEmployee(Enum):
    PM = 1
    ANALYST = 2
    MANAGER = 3

class EngEmployee(Enum):
    DATA_ENG = 1
    FRONTEND_DEV = 2
    BACKEND_DEV = 3

尝试创建统一的Employee枚举但遇到类型检查问题:

class Employee(Enum):
    PM = ProductEmployee.PM
    ANALYST = ProductEmployee.ANALYST
    MANAGER = ProductEmployee.MANAGER
    DATA_ENG = EngEmployee.DATA_ENG
    FRONTEND_DEV = EngEmployee.FRONTEND_DEV
    BACKEND_DEV = EngEmployee.BACKEND_DEV

此时Employee.PM只能被识别为Employee类型,无法直接通过isinstance判断它属于ProductEmployee,必须借助._value_,这种写法不够规范。

可行解决方案

方案1:基于抽象基类(ABC)实现类型层级

将Employee定义为抽象基类,让部门枚举同时继承Enum和Employee,既保留自身类型,又能被识别为总员工类型:

from enum import Enum
from abc import ABC, abstractmethod

class Employee(ABC):
    @abstractmethod
    def __str__(self):
        pass

    # 可选:添加统一访问入口
    PM = ProductEmployee.PM
    ANALYST = ProductEmployee.ANALYST
    MANAGER = ProductEmployee.MANAGER
    DATA_ENG = EngEmployee.DATA_ENG
    FRONTEND_DEV = EngEmployee.FRONTEND_DEV
    BACKEND_DEV = EngEmployee.BACKEND_DEV

class ProductEmployee(Enum, Employee):
    PM = 1
    ANALYST = 2
    MANAGER = 3

class EngEmployee(Enum, Employee):
    DATA_ENG = 1
    FRONTEND_DEV = 2
    BACKEND_DEV = 3

测试验证:

print(isinstance(ProductEmployee.PM, ProductEmployee)) # True
print(isinstance(ProductEmployee.PM, Employee))        # True
print(isinstance(Employee.PM, ProductEmployee))        # True

方案2:自定义元类修改类型检查逻辑

通过自定义Enum元类,让父枚举的实例能被识别为对应子枚举类型,无需修改现有枚举的继承关系:

from enum import EnumMeta, Enum

class HierarchicalEnumMeta(EnumMeta):
    def __instancecheck__(cls, instance):
        # 先检查是否属于当前枚举类
        if super().__instancecheck__(instance):
            return True
        # 再检查实例的原始值是否属于子枚举类型
        if hasattr(instance, '_value_'):
            return any(isinstance(instance._value_, member.value) for member in cls.__members__.values())
        return False

class ProductEmployee(Enum):
    PM = 1
    ANALYST = 2
    MANAGER = 3

class EngEmployee(Enum):
    DATA_ENG = 1
    FRONTEND_DEV = 2
    BACKEND_DEV = 3

class Employee(Enum, metaclass=HierarchicalEnumMeta):
    PM = ProductEmployee.PM
    ANALYST = ProductEmployee.ANALYST
    MANAGER = ProductEmployee.MANAGER
    DATA_ENG = EngEmployee.DATA_ENG
    FRONTEND_DEV = EngEmployee.FRONTEND_DEV
    BACKEND_DEV = EngEmployee.BACKEND_DEV

测试验证:

print(isinstance(Employee.PM, Employee))                # True
print(isinstance(Employee.PM, ProductEmployee))         # True

方案3:子枚举直接继承父枚举

如果所有子枚举的成员值可以保证唯一,直接让部门枚举继承总员工枚举,父枚举会自动包含所有子枚举成员:

from enum import Enum

class Employee(Enum):
    pass

class ProductEmployee(Employee):
    PM = 1
    ANALYST = 2
    MANAGER = 3

class EngEmployee(Employee):
    DATA_ENG = 4  # 必须保证值不与其他子枚举重复
    FRONTEND_DEV = 5
    BACKEND_DEV = 6

测试验证:

print(isinstance(ProductEmployee.PM, ProductEmployee)) # True
print(isinstance(ProductEmployee.PM, Employee))        # True
print(Employee.PM) # 可直接通过父类访问成员

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:53:12