1. 基本使用
定义和访问
from enum import Enum, IntEnum, Flag, auto# 基础枚举class Color(Enum): RED = 1 GREEN = 2 BLUE = 3class Priority(IntEnum): LOW = 1 MEDIUM = 2 HIGH = 3# 访问方式print(Color.RED) # Color.REDprint(Color.RED.name) # 'RED'print(Color.RED.value) # 1# 通过值获取枚举print(Color(1)) # Color.REDprint(Color['RED']) # Color.RED
2. 遍历枚举
class Status(Enum): PENDING = 'pending' RUNNING = 'running' COMPLETED = 'completed' FAILED = 'failed'# 遍历所有成员for status in Status: print(f"{status.name}: {status.value}")# 输出:# PENDING: pending# RUNNING: running# COMPLETED: completed# FAILED: failed# 获取所有成员列表members = list(Status)print(members) # [<Status.PENDING: 'pending'>, ...]# 获取所有名称names = [member.name for member in Status]print(names) # ['PENDING', 'RUNNING', 'COMPLETED', 'FAILED']# 获取所有值values = [member.value for member in Status]print(values) # ['pending', 'running', 'completed', 'failed']
3. 比较操作
class Day(Enum): MON = 'Monday' TUE = 'Tuesday' WED = 'Wednesday'# 身份比较day1 = Day.MONday2 = Day.MONday3 = Day.TUEprint(day1 is day2) # Trueprint(day1 is Day.MON) # Trueprint(day1 is not day3) # True# 值比较print(day1 == Day.MON) # Trueprint(day1 == day3) # Falseprint(day1 != Day.TUE) # True# 不支持大小比较(除非是 IntEnum)class Level(IntEnum): LOW = 1 MEDIUM = 2 HIGH = 3print(Level.LOW < Level.HIGH) # True (仅 IntEnum 支持)
4. 在函数和方法中使用
from enum import Enumfrom typing import Listclass UserRole(Enum): ADMIN = 'admin' EDITOR = 'editor' VIEWER = 'viewer' GUEST = 'guest'class User: def __init__(self, name: str, role: UserRole): self.name = name self.role = role def has_permission(self, required_roles: List[UserRole]) -> bool: """检查用户是否有权限""" return self.role in required_roles def upgrade_role(self, new_role: UserRole): """升级用户角色""" if new_role not in UserRole: raise ValueError(f"Invalid role: {new_role}") self.role = new_role# 使用user = User("Alice", UserRole.VIEWER)print(user.has_permission([UserRole.ADMIN, UserRole.EDITOR])) # Falseprint(user.has_permission([UserRole.VIEWER, UserRole.GUEST])) # True
5. 在数据验证中使用
from enum import Enumfrom pydantic import BaseModel, validatorclass ProductCategory(Enum): ELECTRONICS = 'electronics' CLOTHING = 'clothing' BOOKS = 'books' FOOD = 'food'class Product(BaseModel): name: str price: float category: ProductCategory @validator('category') def validate_category(cls, v): if v not in ProductCategory: raise ValueError(f'Invalid category. Must be one of: {[c.value for c in ProductCategory]}') return v# 使用try: product = Product( name="Laptop", price=999.99, category=ProductCategory.ELECTRONICS ) print(product.category.value) # 'electronics'except ValueError as e: print(f"Error: {e}")
6. 模式匹配(Python 3.10+)
from enum import Enumclass HTTPStatus(Enum): OK = 200 CREATED = 201 BAD_REQUEST = 400 NOT_FOUND = 404 INTERNAL_ERROR = 500def handle_response(status: HTTPStatus): match status: case HTTPStatus.OK | HTTPStatus.CREATED: return "Success" case HTTPStatus.BAD_REQUEST: return "Client error" case HTTPStatus.NOT_FOUND: return "Resource not found" case HTTPStatus.INTERNAL_ERROR: return "Server error" case _: return "Unknown status"# 使用print(handle_response(HTTPStatus.OK)) # "Success"print(handle_response(HTTPStatus.NOT_FOUND)) # "Resource not found"
7. 结合字典使用
from enum import Enumclass ErrorCode(Enum): VALIDATION_ERROR = 1001 AUTH_ERROR = 1002 NOT_FOUND = 1003# 错误信息映射ERROR_MESSAGES = { ErrorCode.VALIDATION_ERROR: "输入数据验证失败", ErrorCode.AUTH_ERROR: "认证失败,请重新登录", ErrorCode.NOT_FOUND: "请求的资源不存在"}# 配置映射CONFIG = { ErrorCode.VALIDATION_ERROR: {"retry": False, "log_level": "warning"}, ErrorCode.AUTH_ERROR: {"retry": True, "log_level": "error"},}def handle_error(error: ErrorCode): message = ERROR_MESSAGES.get(error, "未知错误") config = CONFIG.get(error, {}) print(f"Error {error.value}: {message}") print(f"Config: {config}")
8. 序列化和反序列化
import jsonfrom enum import Enumfrom typing import Anyfrom dataclasses import dataclass, asdictclass OrderStatus(Enum): PENDING = "pending" PROCESSING = "processing" SHIPPED = "shipped" DELIVERED = "delivered"@dataclassclass Order: id: int customer: str status: OrderStatus def to_dict(self) -> dict: return { 'id': self.id, 'customer': self.customer, 'status': self.status.value # 使用 .value 序列化 } @classmethod def from_dict(cls, data: dict) -> 'Order': return cls( id=data['id'], customer=data['customer'], status=OrderStatus(data['status']) # 从值反序列化 )# 使用order = Order(1, "Alice", OrderStatus.PENDING)# 序列化为 JSONorder_dict = order.to_dict()json_str = json.dumps(order_dict)print(json_str) # {"id": 1, "customer": "Alice", "status": "pending"}# 反序列化data = json.loads(json_str)restored_order = Order.from_dict(data)print(restored_order.status) # OrderStatus.PENDING
9. Flag 枚举的位运算
from enum import Flag, autoclass Permission(Flag): NONE = 0 READ = auto() # 1 WRITE = auto() # 2 EXECUTE = auto() # 4 ALL = READ | WRITE | EXECUTE # 7class User: def __init__(self, name: str, permissions: Permission): self.name = name self.permissions = permissions def has_permission(self, permission: Permission) -> bool: return permission in self.permissions def add_permission(self, permission: Permission): self.permissions |= permission def remove_permission(self, permission: Permission): self.permissions &= ~permission# 使用user = User("Bob", Permission.READ | Permission.WRITE)print(user.has_permission(Permission.READ)) # Trueprint(user.has_permission(Permission.EXECUTE)) # Falseuser.add_permission(Permission.EXECUTE)print(user.permissions) # Permission.READ|WRITE|EXECUTEuser.remove_permission(Permission.WRITE)print(user.permissions) # Permission.READ|EXECUTE
10. 实用工具函数
from enum import Enumfrom typing import Optional, Listclass TrafficLight(Enum): RED = 'stop' YELLOW = 'caution' GREEN = 'go'# 检查枚举值是否存在def is_valid_light(color: str) -> bool: try: TrafficLight(color) return True except ValueError: return False# 获取枚举描述def get_light_description(color: TrafficLight) -> str: descriptions = { TrafficLight.RED: "完全停止", TrafficLight.YELLOW: "准备停止", TrafficLight.GREEN: "可以通行" } return descriptions.get(color, "未知")# 枚举转换工具class EnumUtils: @staticmethod def get_enum_by_value(enum_class, value): """通过值获取枚举实例""" try: return enum_class(value) except ValueError: return None @staticmethod def get_values(enum_class) -> List: """获取所有枚举值""" return [member.value for member in enum_class] @staticmethod def get_names(enum_class) -> List[str]: """获取所有枚举名称""" return [member.name for member in enum_class]# 使用print(is_valid_light('stop')) # Trueprint(get_light_description(TrafficLight.RED)) # "完全停止"light = EnumUtils.get_enum_by_value(TrafficLight, 'go')print(light) # TrafficLight.GREEN
最佳实践建议
使用有意义的名称:枚举成员名称应该清晰表达其含义
值保持稳定:枚举值一旦确定不应轻易改变
类型提示:使用枚举作为类型提示可以提高代码可读性
适当文档:为复杂的枚举添加文档字符串
考虑序列化:如果需要序列化,确保值是可序列化的类型