1. 枚举模块 enum
python 的枚举是使用类来实现的,类属性是枚举名称,属性值对应枚举值。Enum 的使用有如下特点:
枚举类不允许定义相同枚举名称,但不同的枚举名称可以有相同的值,后者相当于前者的别名。
枚举值不能被修改,枚举值一旦被修改,就会引发 AttributeError 异常。
两个不同的枚举类,枚举名称和枚举值即便相同,在比较时也是不相等的。
枚举类的一个枚举有 name(标签)和 value(枚举值)两个属性,使用枚举值时,务必通过 value 获取枚举值。
2. 枚举使用实例
python3 提供了 enum 模块,定义类时继承 enum.Enum,可以创建一个枚举类型数据,除此以外还可以继承 enum.IntEnum,枚举值只能是int。
import enumclass ColorCode(enum.Enum):RED = 1BLUE = 2BLACK = 3def print_color(color_code):if color_code == ColorCode.RED.value:print('红色')elif color_code == ColorCode.BLUE.value:print('蓝色')elif color_code == ColorCode.BLACK.value:print('黑色')print_color(1)
枚举值不能被修改,是使用枚举类型进行编程的最重要的目的之一,假设枚举值可以被修改,那么也就没有必要提供 enum 这个模块了,我们使用自定义类和类属性就能够替代 enum 模块。
如果执行:
ColorCode.RED = 4
将会引发错误
raise AttributeError('Cannot reassign members.')
AttributeError: Cannot reassign members.
3. 枚举值
3.1. 枚举值唯一
枚举值理论上是允许重复的,如果不希望出现枚举值重复的情况,可以使用 enum 模块提供的 unique 装饰器
import enum
from enum import unique@unique
class ColorCode(enum.Enum):RED = 1BLUE = 1BLACK = 3
如果枚举值出现了重复的情况,由于有 unique 装饰器修饰,在执行时会报错。
3.2. 枚举值遍历
使用 for 循环可以对枚举值进行遍历,枚举有 name 和 value 两个属性,name 就是枚举类的类属性,value 则是类属性的值。
import enum
from enum import unique@unique
class ColorCode(enum.Enum):RED = 1BLUE = 2BLACK = 3for color in ColorCode:print(color.name, color.value)
程序输出结果:
RED 1
BLUE 2
BLACK 3
3.3. 枚举值比较
两个枚举值之间只支持身份运算符 is 和比较运算符 == 进行比较。
print(ColorCode.RED == ColorCode.RED) # True
这看起来没有什么特别,但如果使用枚举和对应的值进行比较,就会产生一些出乎意料的结果
print(ColorCode.RED == 1) # False
这是非常容易出错的地方,很多人相当然的认为 ColorCode.RED 与 1 是相等的,但真实的结果却是 False,RED 是一项枚举,枚举有name 和 value 两个属性,必须通过 value 才能获得真实的枚举值
print(ColorCode.RED.value == 1) # True
或者换一个思路,将枚举值转成枚举类型
print(ColorCode.RED == ColorCode(1)) # True
3.4. 是否属于枚举
print(2 in {item.value for item in Color}) # True
4. 实例
from enum import Enum# 定义一个枚举类型
class Color(Enum):RED = 1GREEN = 2BLUE = 3# # 要判断的值
# value_to_check = 2# # 判断值是否在枚举的有效范围内
# is_in_enum_range = value_to_check in Color.__members__# print(is_in_enum_range) # 输出: False
print(Color.__members__.keys()) # dict_keys(['RED', 'GREEN', 'BLUE'])
print(Color.__members__.values()) # dict_values([<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>])