枚举
枚举(Enumeration)是一组 有名字的常量值。它的核心用途是:
让一组固定的、有限的值变得更清晰、更安全、更易维护。
比如:星期、颜色、状态码、权限等级等。
没有枚举
1 2 3 4 5
| if status == 1: print("已启动") elif status == 2: print("已停止")
|
这段代码有问题:
- 可读性差:1 和 2 代表什么?
- 不安全:可能随意传入 3、“abc” 等错误值。
使用枚举
1 2 3 4 5 6 7 8 9 10
| from enum import Enum
class Status(Enum): STARTED = 1 STOPPED = 2
status = Status.STARTED print(status) print(status.name) print(status.value)
|
枚举让代码语义更明确、类型更安全。
基本用法
定义枚举类
1 2 3 4 5 6
| from enum import Enum
class Color(Enum): RED = 1 GREEN = 2 BLUE = 3
|
访问成员
1 2 3
| Color.RED Color.RED.name Color.RED.value
|
遍历枚举
1 2 3 4 5
| for color in Color: print(color)
|
比较
1 2 3
| Color.RED == Color.RED Color.RED == Color.GREEN Color.RED is Color.RED
|
关键特性
成员唯一性
枚举成员 必须唯一:
1 2 3 4 5 6
| class Status(Enum): OK = 1 ERROR = 1
print(Status.OK is Status.ERROR) print(list(Status))
|
如果希望禁止别名,可以使用 @unique 装饰器:
1 2 3 4 5 6
| from enum import Enum, unique
@unique class Status(Enum): OK = 1 ERROR = 1
|
枚举是不可变的
不能修改已有成员:
成员可以用名字或值访问
特殊类型的枚举
Python 的 enum 模块提供几种特殊枚举类型:
| 类型 |
说明 |
Enum |
普通枚举 |
IntEnum |
值必须是整数,可与 int 比较 |
Flag / IntFlag |
位运算标志枚举 |
StrEnum (Python 3.11+) |
值自动是字符串,等于成员名 |
IntEnum(与数字兼容)
1 2 3 4 5 6 7 8 9
| from enum import IntEnum
class Level(IntEnum): LOW = 1 MEDIUM = 2 HIGH = 3
print(Level.LOW == 1) print(Level.LOW < Level.HIGH)
|
普通 Enum 不支持这种比较。
Flag / IntFlag(位标志)
适合“可组合的状态”,比如文件权限:
1 2 3 4 5 6 7 8 9 10
| from enum import Flag, auto
class Permission(Flag): READ = auto() WRITE = auto() EXECUTE = auto()
perm = Permission.READ | Permission.WRITE print(perm) print(Permission.READ in perm)
|
StrEnum(字符串值)
Python 3.11+ 加入,可以自动使用字符串值:
1 2 3 4 5
| from enum import StrEnum
class Color(StrEnum): RED = "RED" GREEN = "GREEN"
|
或者更简洁:
1 2 3 4 5
| class Color(StrEnum): RED = auto() GREEN = auto()
print(Color.RED.value)
|
高级技巧
自动赋值
1 2 3 4 5 6 7 8 9
| from enum import Enum, auto
class Color(Enum): RED = auto() GREEN = auto() BLUE = auto()
print(list(Color))
|
自定义方法与属性
1 2 3 4 5 6
| class Status(Enum): STARTED = 1 STOPPED = 2
def describe(self): return f"{self.name} ({self.value})"
|
1
| Status.STARTED.describe()
|
混合类型枚举
可继承内建类型(如 str、int):
1 2 3
| class HttpStatus(int, Enum): OK = 200 NOT_FOUND = 404
|
这样可以与数字比较:
应用场景举例
| 场景 |
示例 |
| 状态机 |
class State(Enum): IDLE = 0; RUNNING = 1; STOPPED = 2 |
| HTTP 状态码 |
class HTTP(Enum): OK=200; NOT_FOUND=404 |
| 颜色常量 |
class Color(Enum): RED=1; GREEN=2; BLUE=3 |
| 文件权限 |
class Perm(Flag): READ=1; WRITE=2; EXECUTE=4 |
枚举 vs 普通常量
| 对比项 |
普通常量 |
Enum 枚举 |
| 可读性 |
一般 |
✅ 明确 |
| 可扩展性 |
差 |
✅ 强 |
| 比较安全性 |
可能传入错误值 |
✅ 受限于定义 |
| 类型检查 |
不支持 |
✅ 支持 |
| 调试可读性 |
差(1,2,3) |
✅ 清晰(Color.RED) |
总结表
| 特点 |
说明 |
| ✅ 枚举是命名常量集合 |
让代码更清晰、安全 |
🧱 通过继承 Enum 定义 |
每个成员是唯一对象 |
💬 可通过 .name / .value 访问 |
支持遍历和比较 |
🧮 特殊类型:IntEnum、Flag、StrEnum |
用于不同场景 |
🚀 支持 auto()、unique、自定义方法 |
高度可扩展 |