Python中的枚举

540 阅读2分钟

这是我参与更文挑战的第13天,活动详情查看: 更文挑战

业务场景

众所周知, 枚举是我们大型外包公司开发中非常重要的一个概念, 可以列举出它的无数使用场景:

  1. 逻辑删除中的是否删除属性
  2. 业务中的类型相关属性
  3. 流程中的状态相关

对于中华民族而言, 无论是在Java还是Python中, 枚举都缺少了一个重要的部分, 就是它的中文含义

本文会先简单介绍下Python中枚举的使用, 之后对其进行派生, 创建一个适合我们业务场景的枚举类

方案

先把Python官方中文文档的枚举部分链接贴在这里, 有需要的小伙伴可以查看, 下面的内容为笔者的总结

Enum和IntEnum

Python中创建枚举十分简单, 例如状态:

from enum import Enum

class Status(Enum):
    STOP = -1
    INIT = 0
    START = 1

其中的STOP/INIT/START是枚举的名称, -1/0/1是枚举的值

我们可以使用Status.STOP.name来获取枚举的名称, Status.STOP.value获取枚举的值

枚举可以进行比较, 如Status.STOP == Status.INIT, 结果为False

需要注意的是, Status.STOP == -1的结果为False

说到这里, 我们可引出另一个枚举, IntEnum

看到名字小伙伴们大概也明白了, 它是可以和整型进行直接比较的, 我们只需要让Status继承IntEnum, 之后Status.STOP == -1的结果就是True了

但是IntEnum仍然不可以和Enum进行比较哦

自定义NameEnum

在前端对枚举进行展示时, 大部分情形是需要中文的

笔者非常不建议前端后端维护两套相同的枚举内容, 所有和数据相关的内容(枚举/字典等)都应交给后台接口

在Python中, 我们可以利用枚举的__new__方法进行实现, 直接上代码:

from enum import IntEnum


class NameEnum(IntEnum):
    def __new__(cls, value, desc):
        obj = int.__new__(cls)
        obj._value_ = value
        obj.desc = desc
        return obj

我们基于IntEnum派生了一个NameEnum, 它的__new__方法接收一个desc的参数, 用于记录枚举的中文描述, 接下来我们改造下之前的Status:

class Status(NameEnum):
    STOP = (-1, '停止')
    INIT = (0, '初始化')
    START = (1, '启动')

这样我们就可以使用枚举的描述了哦:

print(Status.INIT.name) // STOP
print(Status.INIT.value) // 0
print(Status.INIT.desc) // 初始化