Python 3.4+ 枚举类型 Enum 详解:定义、取值与比较
本文详解Python 3.4引入的enum标准库。涵盖枚举的定义、成员取值、迭代遍历及唯一性约束(@unique)。重点解析枚举成员的同一性与等值比较规则,说明为何不支持大小比较,并介绍IntEnum扩展类以实现整数枚举间的跨类型比较。
起步
Python 原生类型中并未内置枚举类型。为提供更完善的解决方案,Python 依据 PEP 435 规范,在 3.4 版本中正式引入了 enum 标准库。
枚举类型可视为一种标签或一系列常量的集合,通常用于表示特定的有限集合,例如星期、月份或状态等。在未提供专用枚举类型时,常见的替代方案是通过字典或类来实现:
Color = {
'RED' : 1,
'GREEN': 2,
'BLUE' : 3,
}
class Color:
RED = 1
GREEN = 2
BLUE = 3
采用这种方式实现枚举,若使用谨慎则通常不会出现问题,但这毕竟是一种妥协方案。其潜在隐患在于这些常量值可能被意外修改。
使用 Enum
更推荐的方式是使用标准库提供的 Enum 类型,官方库的可靠性值得信赖。对于 3.4 之前的 Python 版本,可通过执行 pip install enum 命令安装支持库。简单示例如下:
from enum import Enum class Color(Enum): red = 1 green = 2 blue = 3
枚举成员包含值(默认情况下值可重复),且枚举成员具有友好的字符串表示形式:
>>> print(Color.red) Color.red >>> print(repr(Color.red)) <Color.red: 1> >>> type(Color.red) <Enum 'Color'> >>> isinstance(Color.green, Color) True
枚举类型不可实例化,且其成员值不可更改。
定义枚举
在定义枚举时,成员名不允许重复。
class Color(Enum): red = 1 green = 2 red = 3 # TypeError: Attempted to reuse key: 'red'
成员值允许相同,此时第二个成员的名称被视为第一个成员的别名。
class Color(Enum): red = 1 green = 2 blue = 1 print(Color.red) # Color.red print(Color.blue) # Color.red print(Color.red is Color.blue)# True print(Color(1)) # Color.red 在通过值获取枚举成员时,只能获取到第一个成员
若需禁止定义相同的成员值,可通过 unique 装饰器进行约束。
from enum import Enum, unique @unique class Color(Enum): red = 1 green = 2 blue = 1 # ValueError: duplicate values found in <enum 'Color'>: blue -> red
枚举取值
既可以通过成员名获取成员,也可以通过成员值获取成员:
print(Color['red']) # Color.red 通过成员名来获取成员 print(Color(1)) # Color.red 通过成员值来获取成员
每个成员均包含名称属性和值属性:
member = Color.red print(member.name) # red print(member.value) # 1
支持以迭代方式遍历成员,按定义顺序进行。若存在值重复的成员,迭代时仅获取重复序列中的第一个成员:
for color in Color: print(color)
特殊属性 __members__ 是一个将名称映射到成员的有序字典,也可通过该属性完成遍历:
for color in Color.__members__.items():
print(color) # ('red', <Color.red: 1>)
枚举比较
枚举成员可通过 is 进行同一性比较,或通过 == 进行等值比较:
Color.red is Color.red Color.red is not Color.blue Color.blue == Color.red Color.blue != Color.red
枚举成员之间不支持大小比较:
Color.red < Color.blue # TypeError: unorderable types: Color() < Color()
扩展枚举 IntEnum
IntEnum 是 Enum 的扩展,允许不同类型的整数枚举之间相互比较:
from enum import IntEnum class Shape(IntEnum): circle = 1 square = 2 class Request(IntEnum): post = 1 get = 2 print(Shape.circle == 1) # True print(Shape.circle < 3) # True print(Shape.circle == Request.post) # True print(Shape.circle >= Request.post) # True
总结
enum 模块功能明确且用法简单,其内部实现方式也值得深入学习,如有兴趣可查阅其源码。
以上为本文的全部内容,希望本文内容对大家的学习或工作具有一定的参考借鉴价值。如有疑问欢迎留言交流,感谢大家对本站的支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









