枚举

枚举(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) # Status.STARTED
print(status.name) # 'STARTED'
print(status.value) # 1

枚举让代码语义更明确、类型更安全。

基本用法

定义枚举类

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: 1>
Color.RED.name # 'RED'
Color.RED.value # 1

遍历枚举

1
2
3
4
5
for color in Color:
print(color)
# Color.RED
# Color.GREEN
# Color.BLUE

比较

1
2
3
Color.RED == Color.RED     # True
Color.RED == Color.GREEN # False
Color.RED is Color.RED # True

关键特性

成员唯一性

枚举成员 必须唯一

1
2
3
4
5
6
class Status(Enum):
OK = 1
ERROR = 1 # 不会报错,但自动成为别名

print(Status.OK is Status.ERROR) # True
print(list(Status)) # [<Status.OK: 1>]

如果希望禁止别名,可以使用 @unique 装饰器:

1
2
3
4
5
6
from enum import Enum, unique

@unique
class Status(Enum):
OK = 1
ERROR = 1 # ❌ ValueError: duplicate values found

枚举是不可变的

不能修改已有成员:

1
Color.RED = 10  # ❌ TypeError

成员可以用名字或值访问

1
2
Color['RED']     # <Color.RED: 1>
Color(1) # <Color.RED: 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) # ✅ True
print(Level.LOW < Level.HIGH) # ✅ True

普通 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) # Permission.READ|WRITE
print(Permission.READ in perm) # True

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) # 'RED'

高级技巧

自动赋值

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))
# [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]

自定义方法与属性

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()  # 'STARTED (1)'

混合类型枚举

可继承内建类型(如 strint):

1
2
3
class HttpStatus(int, Enum):
OK = 200
NOT_FOUND = 404

这样可以与数字比较:

1
HttpStatus.OK == 200  # True

应用场景举例

场景 示例
状态机 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 访问 支持遍历和比较
🧮 特殊类型:IntEnumFlagStrEnum 用于不同场景
🚀 支持 auto()unique、自定义方法 高度可扩展