27 enum枚举
你定义了一堆状态码:PENDING = 0、ACTIVE = 1、INACTIVE = 2。问题是,这些魔法数字谁记得住?传个3进去谁知道是什么意思?enum模块就是来解决这个问题的,它让你定义有意义的枚举类型。
一、基本用法
1.1 定义枚举
python
from enum import Enum
class Status(Enum):
PENDING = 0
ACTIVE = 1
INACTIVE = 2
# 使用
print(Status.ACTIVE) # Status.ACTIVE
print(Status.ACTIVE.name) # 'ACTIVE'
print(Status.ACTIVE.value) # 11.2 访问枚举成员
python
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# 通过名称访问
print(Color.RED) # Color.RED
# 通过值访问
print(Color(1)) # Color.RED
# 比较
print(Color.RED == Color.RED) # True
print(Color.RED == Color.GREEN) # False
# 遍历
for color in Color:
print(f"{color.name}: {color.value}")1.3 函数式创建
python
from enum import Enum
Color = Enum('Color', ['RED', 'GREEN', 'BLUE'])
print(Color.RED) # Color.RED
print(Color.RED.value) # 1(自动从1开始)二、auto():自动递增
python
from enum import Enum, auto
class Direction(Enum):
NORTH = auto() # 1
SOUTH = auto() # 2
EAST = auto() # 3
WEST = auto() # 4
print(Direction.NORTH.value) # 1
print(Direction.SOUTH.value) # 2三、IntEnum:整数枚举
可以当作整数使用。
python
from enum import IntEnum
class Priority(IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
# 可以比较大小
print(Priority.HIGH > Priority.LOW) # True
# 可以和整数运算
print(Priority.HIGH + 1) # 4
# 可以用于需要整数的地方
def process(level: int):
print(f"处理级别: {level}")
process(Priority.HIGH) # OK四、StrEnum:字符串枚举(3.11+)
python
from enum import StrEnum
class Color(StrEnum):
RED = "red"
GREEN = "green"
BLUE = "blue"
# 可以当作字符串使用
print(f"颜色是 {Color.RED}") # 颜色是 red
print(Color.RED.upper()) # RED五、Flag:位标志枚举
支持位运算。
python
from enum import Flag, auto
class Permission(Flag):
READ = auto() # 1
WRITE = auto() # 2
EXECUTE = auto() # 4
ALL = READ | WRITE | EXECUTE # 7
# 组合权限
perms = Permission.READ | Permission.WRITE
print(perms) # Permission.READ|WRITE
# 检查权限
print(Permission.READ in perms) # True
print(Permission.EXECUTE in perms) # False
# 添加权限
perms |= Permission.EXECUTE
print(perms) # Permission.READ|WRITE|EXECUTE5.1 IntFlag
整数版本的Flag。
python
from enum import IntFlag
class Color(IntFlag):
RED = 1
GREEN = 2
BLUE = 4
# 可以和整数运算
mixed = Color.RED | Color.GREEN
print(mixed) # Color.RED|GREEN
print(mixed.value) # 3六、@unique:值唯一
python
from enum import Enum, unique
@unique
class Status(Enum):
PENDING = 0
ACTIVE = 1
INACTIVE = 2
# DUPLICATE = 0 # ValueError: duplicate values found七、枚举方法
7.1 自定义方法
python
from enum import Enum
class Planet(Enum):
MERCURY = (3.303e+23, 2.4397e6)
VENUS = (4.869e+24, 6.0518e6)
EARTH = (5.976e+24, 6.37814e6)
def __init__(self, mass, radius):
self.mass = mass
self.radius = radius
def surface_gravity(self):
G = 6.67300E-11
return G * self.mass / (self.radius ** 2)
print(Planet.EARTH.surface_gravity()) # 9.8...7.2 类方法
python
from enum import Enum
class Season(Enum):
SPRING = 1
SUMMER = 2
AUTUMN = 3
WINTER = 4
@classmethod
def from_month(cls, month):
if month in (3, 4, 5):
return cls.SPRING
elif month in (6, 7, 8):
return cls.SUMMER
elif month in (9, 10, 11):
return cls.AUTUMN
else:
return cls.WINTER
print(Season.from_month(6)) # Season.SUMMER八、实战场景
8.1 状态机
python
from enum import Enum
class OrderStatus(Enum):
CREATED = "created"
PAID = "paid"
SHIPPED = "shipped"
DELIVERED = "delivered"
CANCELLED = "cancelled"
class Order:
def __init__(self):
self.status = OrderStatus.CREATED
def pay(self):
if self.status != OrderStatus.CREATED:
raise ValueError(f"无法从{self.status}转换到已支付")
self.status = OrderStatus.PAID
def ship(self):
if self.status != OrderStatus.PAID:
raise ValueError(f"无法从{self.status}转换到已发货")
self.status = OrderStatus.SHIPPED8.2 配置常量
python
from enum import Enum
class LogLevel(Enum):
DEBUG = 10
INFO = 20
WARNING = 30
ERROR = 40
CRITICAL = 50
class Config:
def __init__(self):
self.log_level = LogLevel.INFO
def should_log(self, level: LogLevel):
return level.value >= self.log_level.value
config = Config()
print(config.should_log(LogLevel.DEBUG)) # False
print(config.should_log(LogLevel.ERROR)) # True8.3 错误码
python
from enum import IntEnum
class ErrorCode(IntEnum):
SUCCESS = 0
INVALID_INPUT = 1001
NOT_FOUND = 1002
PERMISSION_DENIED = 1003
INTERNAL_ERROR = 5000
def process(data):
if not data:
return ErrorCode.INVALID_INPUT
return ErrorCode.SUCCESS
result = process(None)
if result != ErrorCode.SUCCESS:
print(f"错误: {result.name} ({result.value})")九、枚举的限制
9.1 不能修改值
python
from enum import Enum
class Color(Enum):
RED = 1
# Color.RED = 2 # AttributeError: Cannot reassign members9.2 值可以重复(除非用@unique)
python
from enum import Enum
class Color(Enum):
RED = 1
CRIMSON = 1 # OK,和RED是同一个值
BLUE = 2
print(Color.CRIMSON is Color.RED) # True十、总结
enum模块的核心:
| 类 | 用途 |
|---|---|
Enum | 基础枚举 |
IntEnum | 整数枚举 |
StrEnum | 字符串枚举(3.11+) |
Flag | 位标志枚举 |
IntFlag | 整数位标志 |
auto() | 自动递增值 |
@unique | 确保值唯一 |
使用场景:
- 状态码、错误码
- 配置常量
- 类型标识
- 权限标志
比直接用数字或字符串好:有类型检查、有自动补全、代码更清晰。