Python 枚举(Enum)使用教程
枚举(Enum)是Python 3.4+版本引入的标准库核心功能,专门用于定义一组语义明确、不可修改、取值受限的命名常量。相比传统靠开发者约定俗成的大写变量(比如MONTH_JAN = 1),它能提供静态检查(避免打错字、传非法值)、语义可读性、遍历/访问规范化等优势,是写生产级代码时的常用工具。
基本枚举定义
方式1:工厂函数快速创建
如果只是简单用一组顺序递增的默认值(从1开始,0需自定义),可以用Enum的工厂函数快速生成:
这种方式生成的枚举,每个成员有两个固定属性:
name:成员的字符串名称(如Month.Jan.name是'Jan')value:成员的分配值(如Month.Jan.value是1)
方式2:自定义枚举类(生产推荐)
更灵活、更易维护的方式是继承Enum基类创建子类,可以搭配装饰器和自定义值使用:
枚举成员的常用访问方式
枚举成员的访问不能直接用==和整数值/字符串比较语义(除非用特殊子类),推荐用以下4种规范化方式:
枚举的高级实用特性
自动赋值
如果成员值不重要,只需要区分,可以用auto()自动分配连续值(默认从1开始,继承IntFlag/StrEnum等会调整规则):
自定义成员值 + 绑定额外属性/方法
枚举成员的值不一定是整数/字符串,可以是任意类型;同时枚举类可以像普通类一样定义__init__、实例方法、类方法,绑定业务相关的逻辑:
遍历枚举成员
可以通过__members__属性遍历所有成员(包括别名?不过用了@unique就没有别名了):
实际应用示例:身份信息中的性别枚举
传统的代码可能用0/1/2表示性别,但可读性差、容易传错;用枚举就能完全解决:
Python 3.11+ 新增的便捷子类
如果枚举的成员值必须是字符串/整数,或者需要和对应类型直接兼容(比如LogLevel.INFO == "info"直接返回True),可以用3.11+新增的StrEnum/IntEnum/IntFlag等子类:
最佳实践总结
- 必须加
@unique:除非有明确需要别名(很少见),否则强制唯一值防止手滑 - 优先用自定义子类:相比工厂函数,子类更灵活、易扩展、易文档化
- 避免直接用值/字符串比较语义:除非用
StrEnum/IntEnum,否则用枚举成员本身比较 - 业务逻辑绑定到枚举:比如上面的行星重力、或者状态流转规则,尽量放在枚举类里,提高内聚性
- 命名规范:枚举类名用大驼峰(如
Weekday),成员名用全大写(如MONDAY),符合Python约定
总结
Python的枚举解决了传统常量定义的三大痛点:
- 没有语义安全:打错变量名、传非法值不会立即报错
- 没有明确的取值范围:开发者不知道常量可以传哪些值
- 没有业务逻辑内聚:相关逻辑分散在各个地方
虽然它的功能不如某些强类型语言(如Java)丰富,但已经足够满足Python开发的大多数场景,是提高代码质量的重要工具。

