枚举(Enum)
📚 总结
Python 中的枚举(Enum)是一个强大的工具,用于创建具有固定值集合的类。枚举提供了一种清晰、类型安全的方式来表示一组相关的常量:
- 🏗️ 基础结构:继承自
Enum
基类,创建固定值集合(可以使用auto()
自动生成 ) - 🔒 不可变性:保证枚举值在运行时不可修改,使用
@unique
确保枚举值唯一 - 📋 属性访问:通过
name
和value
属性获取信息 - 🔍 类型理解:区分枚举成员、名字和值的不同类型
- 🔄 遍历能力:支持直接迭代所有枚举成员
- ⭐ 枚举运算:通过
==
、is
比较枚举值是否相等,使用IntEnum
进行大小比较 - 💼 实际应用:枚举+枚举能力封装举例
📌 注意:枚举功能从 Python 3.4 版本开始支持
1. 枚举基类(Enum) 🏗️
基本语法
from enum import Enum
# 类创建
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# 函数式API创建枚举
Animal = Enum('Animal', 'DOG CAT BIRD FISH')
# 或者使用字典
ResponseCode = Enum('ResponseCode', {
'SUCCESS': 200,
'NOT_FOUND': 404,
'ERROR': 500
})
auto()
自动分配
from enum import Enum, auto
class Operation(Enum):
ADD = auto()
SUBTRACT = auto()
MULTIPLY = auto()
DIVIDE = auto()
# 查看自动分配的值
for op in Operation:
print(f"{op.name} = {op.value}")
# 输出:
# ADD = 1
# SUBTRACT = 2
# MULTIPLY = 3
# DIVIDE = 4
📌 版本支持:
auto()
功能从 Python 3.6 版本开始支持💡 重点:枚举成员的值可以是任意类型(整数、字符串、元组等)
2. 枚举值不可改变 🔒
枚举的一个核心特性是其值在创建后无法被修改,这确保了数据的完整性和一致性。
值不可变
from enum import Enum
class Priority(Enum):
LOW = 1
MEDIUM = 2
HIGH = 3
# ❌ 尝试修改枚举值 - 这将抛出异常
try:
Priority.LOW = 10
except AttributeError as e:
print(f"错误:{e}")
# 输出:错误:Cannot reassign members.
# ❌ 尝试删除枚举成员 - 这也将抛出异常
try:
del Priority.LOW
except AttributeError as e:
print(f"错误:{e}")
# 输出:错误:Cannot delete members.
值唯一
使用 @unique
装饰器确保唯一性
from enum import Enum, unique
@unique
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# CRIMSON = 1 # 如果取消注释,会抛出 ValueError
⚠️ 注意:枚举的不可变性是其设计的重要特性,确保了程序中常量的稳定性
3. 获取枚举值和名字 📋
获取枚举的名字和值
from enum import Enum
class Direction(Enum):
NORTH = "N"
SOUTH = "S"
EAST = "E"
WEST = "W"
# 获取枚举成员的名字
print(Direction.NORTH.name) # 输出:NORTH
# 获取枚举成员的值
print(Direction.NORTH.value) # 输出:N
通过值获取枚举成员
# 通过值获取枚举成员
north_direction = Direction("N")
print(north_direction) # 输出:Direction.NORTH
print(north_direction.name) # 输出:NORTH
# 或者使用字典语法
east_direction = Direction["EAST"]
print(east_direction) # 输出:Direction.EAST
print(east_direction.value) # 输出:E
4. 类型区别:type(Enum.xx.name)
vs type(Enum.xx)
🔍
这是一个重要的概念差异,需要深入理解枚举成员的属性类型。
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# 检查 name 属性的类型
print(f"Color.RED.name 的类型:{type(Color.RED.name)}")
# 输出:Color.RED.name 的类型:<class 'str'>
# 检查枚举成员本身的类型
print(f"Color.RED 的类型:{type(Color.RED)}")
# 输出:Color.RED 的类型:<enum 'Color'>
# 检查 value 属性的类型
print(f"Color.RED.value 的类型:{type(Color.RED.value)}")
# 输出:Color.RED.value 的类型:<class 'int'>
📝 总结:
name
属性总是返回 字符串类型value
属性返回定义时指定的类型- 枚举成员本身是枚举类的实例
5. 可遍历特性 🔄
枚举类支持直接遍历,这使得批量处理枚举成员变得非常便捷。
from enum import Enum
class HttpStatus(Enum):
OK = 200
NOT_FOUND = 404
SERVER_ERROR = 500
# 获取所有成员名称
names = [status.name for status in HttpStatus]
print(f"状态名称:{names}")
# 输出:状态名称:['OK', 'NOT_FOUND', 'SERVER_ERROR']
# 获取所有成员值
values = [status.value for status in HttpStatus]
print(f"状态码:{values}")
# 输出:状态码:[200, 404, 500]
# 使用 list() 转换
all_statuses = list(HttpStatus)
print(f"所有状态:{all_statuses}") # [<HttpStatus.OK: 200>, <HttpStatus.NOT_FOUND: 404>, <HttpStatus.SERVER_ERROR: 500>]
6. 枚举运算 ⭐
枚举比较和相等性
from enum import Enum
class Size(Enum):
SMALL = 1
MEDIUM = 2
LARGE = 3
# 相等性比较
print(Size.SMALL == Size.SMALL) # True
print(Size.SMALL == Size.MEDIUM) # False
# 身份比较
print(Size.SMALL is Size.SMALL) # True
# ❌ 不支持大小比较(会抛出异常)
try:
print(Size.SMALL < Size.MEDIUM)
except TypeError as e:
print(f"错误:{e}")
IntEnum
用于数值比较
from enum import IntEnum
class Priority(IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
# IntEnum 支持数值比较
print(Priority.LOW < Priority.HIGH) # True
print(Priority.MEDIUM >= Priority.LOW) # True
# 也可以与整数比较
print(Priority.HIGH == 3) # True
print(Priority.LOW < 5) # True
💡 建议:当需要进行数值比较时,使用
IntEnum
;当只需要标识符时,使用普通的Enum
7. 实际应用示例 💼
from enum import Enum, auto
class UserRole(Enum):
"""用户角色枚举"""
ADMIN = auto()
MODERATOR = auto()
USER = auto()
GUEST = auto()
def has_permission(self, action):
"""检查角色权限"""
permissions = {
UserRole.ADMIN: ['read', 'write', 'delete', 'manage'],
UserRole.MODERATOR: ['read', 'write', 'delete'],
UserRole.USER: ['read', 'write'],
UserRole.GUEST: ['read']
}
return action in permissions.get(self, [])
# 使用示例
user_role = UserRole.USER
print(f"用户角色:{user_role.name}")
print(f"可以写入:{user_role.has_permission('write')}") # True
print(f"可以删除:{user_role.has_permission('delete')}") # False