公司动态
Python模块:内置模块enum枚举类型的创建使用
Python模块内置模块enum枚举类型的创建使用一、开篇告别魔术数字你的代码里有多少这样的魔术数字# ❌ 魔术数字——三个月后谁都看不懂ifstatus1:print(处理中)elifstatus2:print(已完成)elifstatus0:print(已取消)# ✅ 枚举——意图一目了然fromenumimportEnumclassOrderStatus(Enum):CANCELLED0PROCESSING1COMPLETED2ifstatusOrderStatus.PROCESSING:print(处理中) 枚举Enum给一组相关的常量赋予有意义的名字。它提高代码可读性、防止拼写错误、约束取值范围——是消除魔术数字的利器。二、基本使用2.1 创建和访问枚举fromenumimportEnumclassColor(Enum):RED1GREEN2BLUE3# 三种访问方式print(Color.RED)# Color.REDprint(Color[RED])# Color.RED —— 通过名字print(Color(1))# Color.RED —— 通过值# 枚举成员的属性print(Color.RED.name)# RED —— 名字print(Color.RED.value)# 1 —— 值# 比较print(Color.REDColor.RED)# Trueprint(Color.REDColor.BLUE)# Falseprint(Color.REDisColor.RED)# True —— 同一成员是单例# print(Color.RED Color.GREEN) # TypeError —— 不支持大小比较除非IntEnum# 迭代forcolorinColor:print(f{color.name}{color.value})2.2 auto()自动赋值fromenumimportEnum,autoclassStatus(Enum):PENDINGauto()# 1APPROVEDauto()# 2REJECTEDauto()# 3CANCELLEDauto()# 4print([(s.name,s.value)forsinStatus])# [(PENDING, 1), (APPROVED, 2), (REJECTED, 3), (CANCELLED, 4)]# 自定义auto行为classMyAuto(Enum):def_generate_next_value_(name,start,count,last_values):自定义auto生成的valuereturnname.lower()# 用名字的小写作为值classConfigKey(MyAuto):HOSTauto()# hostPORTauto()# portDEBUGauto()# debugprint([(k.name,k.value)forkinConfigKey])三、枚举的变体3.1 IntEnum——可与整数比较fromenumimportIntEnumclassPriority(IntEnum):LOW1MEDIUM3HIGH5URGENT10# IntEnum可以当作整数使用print(Priority.HIGH5)# Trueprint(Priority.HIGHPriority.LOW)# True —— 支持大小比较print(Priority.HIGH1)# 6# 但和普通Enum相比失去了类型安全性# Priority.HIGH 5是True——可能不是你想要的3.2 Flag——位标志fromenumimportFlag,autoclassPermission(Flag):NONE0READauto()# 1WRITEauto()# 2DELETEauto()# 4ADMINREAD|WRITE|DELETE# 7# 组合权限user_permsPermission.READ|Permission.WRITE# 3print(user_perms)# Permission.READ|WRITEprint(Permission.READinuser_perms)# Trueprint(Permission.DELETEinuser_perms)# False# 赋予权限user_perms|Permission.DELETEprint(Permission.ADMINinuser_perms)# True# 实战文件权限系统defcan_access(required,user_permission):检查用户是否有足够的权限returnrequiredinuser_permissionprint(can_access(Permission.READ,Permission.READ|Permission.WRITE))# Trueprint(can_access(Permission.DELETE,Permission.READ|Permission.WRITE))# False四、实战案例4.1 API状态码fromenumimportIntEnumclassHttpStatus(IntEnum):HTTP状态码枚举OK200CREATED201BAD_REQUEST400UNAUTHORIZED401FORBIDDEN403NOT_FOUND404INTERNAL_ERROR500defis_success(self):return200self.value300defis_client_error(self):return400self.value500defhandle_response(status_code,body):处理HTTP响应statusHttpStatus(status_code)ifstatus.is_success():print(f✓{status.name}:{body})elifstatus.is_client_error():print(f✗{status.name}: 客户端错误)else:print(f⚠{status.name}: 服务器错误)handle_response(200,操作成功)handle_response(404,None)4.2 配置选项fromenumimportEnumclassLogLevel(Enum):DEBUG10INFO20WARNING30ERROR40def__ge__(self,other):支持 比较ifself.__class__isother.__class__:returnself.valueother.valuereturnNotImplementedclassLogConfig:current_levelLogLevel.INFOclassmethoddefset_level(cls,level):ifnotisinstance(level,LogLevel):raiseTypeError(f请使用LogLevel枚举而不是{type(level)})cls.current_levellevelclassmethoddefshould_log(cls,level):returnlevelcls.current_level# 使用——类型安全不会传错LogConfig.set_level(LogLevel.DEBUG)print(LogConfig.should_log(LogLevel.INFO))# True五、总结枚举让一组相关的常量有了类型和名字。它是消除魔术数字和提高代码可读性的标准方式。选型指南类型用途特点Enum通用枚举类型安全不可与整型混用IntEnum兼容整数的枚举可与整数比较、运算Flag位标志支持位运算组合auto()自动赋值不关心具体值时使用✅最佳实践枚举名全大写PascalCase类名UPPER_CASE成员名。当你发现代码中有0, 1, 2这样的状态码时——就用枚举。