为什么需要枚举
枚举(Enum)是一种数据类型,也是一种特别的类,是绑定到唯一值的符号表示,可以使用它来创建用于变量和属性的常量集枚举类可以看成是一个下拉菜单,给出特定的选项且这些选项不可修改,更贴近自然语言的方式表达数据,可以让代码更容易阅读、维护,减少转换或者错误值引起的问题,enum定义了四个类 Enum、IntEnum、Flag 和 IntFlag和一个装饰器unique()、辅助类auto
- enum.Enum:创建枚举常量基类,即便定义int,成员也不是整型的,整型相关可以用Int相关类
- enum.IntEnum:用于创建同时也是 int的子类的枚举型常数的基类
- enum.IntFlag:创建可与位运算符搭配使用,成员是int的子类
- enum.Flag:创建可与位运算符搭配使用,又不会失去 Flag成员资格的枚举常量的基类
- 装饰器unique:确保一个名称只绑定一个值的 Enum 类装饰器
- 辅助类auto:以合适的值代替 Enum 成员的实例。 初始值默认从 1 开始
如何使用枚举类型
通过继承enum.Enum定义一个枚举类型
import enum
# 继承Enum创建枚举类型
class Config(enum.Enum):
# 定义枚举成员常量
MAX = 1000
MIN = 10
if __name__ == '__main__':
# 获取枚举成员、值、属性
print(Config.MAX) # Config.MAX
print(Config['MAX']) # Config.MAX
print(repr(Config.MAX)) #
print(type(Config.MAX)) #
print(Config.MAX.name) # MAX
print(Config.MAX.value) # 1000
print(Config(1000)) # Config.MAX
# 通过API定义
Config = enum.Enum('Config',{MAX:1000})
'''
第一个参数是枚举的名称
第二个参数是枚举成员的来源,可以是字符串、元组、字典
'''
我们自定义的枚举类型继承Enum基类,之后还是通过Config.MAX获取得到的是枚举成员,通过.name和.value可以获得枚举成员对应的属性
在枚举类型中定义重复的枚举成员会抛出TypeError: Attempted to reuse key
异常
在类的外部通过Config.MAX = 2的方式修改,会抛出AttributeError: Cannot reassign members
异常
为枚举成员添加额外属性
我们通过.name和.value访问枚举成员的定义名称和值,也可以为枚举成员添加其他属性
获取枚举成员,可以通过key获取,也可以通过value获取枚举成员
if __name__ == '__main__':
Config.MAX.msg = '最大值'
Config.MIN.msg = '最小值'
# 示例一
print(Config.MAX.msg) # 最大值
print(Config.MIN.msg) # 最小值
# 示例二
conf = Config.MAX
print(conf.msg) # 最大值
# 示例三
conf = Config(10)
print(conf.msg) # 最小值
枚举成员迭代
枚举支持按照定义顺序进行迭代
class Config(enum.Enum):
MAX = 1000
MIN = 10
if __name__ == '__main__':
for number in Config:
print(number)
'''
Config.MAX
Config.MIN
'''
特殊属性 __members__
可以迭代从名称到成员的有序映射,包含所有美剧中定义的所有名称,包括别名
# 1.不会给出别名
print(list(Config)) # [, ]
# 2.可以显示别名
for name,number in Config.__members__.items():
print(name,number)
unique装饰器
定义枚举时,成员名称不允许重复,但是默认情况下,不同的成员值允许相同。但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名,如果枚举中存在相同值的成员,在通过值获取枚举成员时,只能获取到第一个成员,如果我们想确保一个枚举类中的成员的值也不会重复,可以使用unique装饰器
@enum.unique
class Config(enum.Enum):
MAX = 1000
MIN = 10
'''
使用该装饰器后,如果有相同的值,会抛出ValueError: duplicate values found
'''
auto()
如果确切的值不重要,可以使用auto()生成值,值将由 _generate_next_value_()
来选择
_generate_next_value_默认是我们定义的最后一个int开始+1,如下示例,TIME的auto值则是11
_generate_next_value_可以重写,必须定义其他成员之前
class Config(enum.Enum):
MAX = 1000
MIN = 10
TIME = enum.auto() # 11
City = enum.auto() # 12
'''
自定义_generate_next_value_
'''
class Config(enum.Enum):
def _generate_next_value_(name, start, count, last_values):
return name # 返回枚举成员的名字
MAX = 1000
MIN = 10
TIME = enum.auto() # TIME
City = enum.auto() # City
比较运算
# 枚举成员按标识号进行比较
Config.MAX is Config.MAX # True
Config.MAX is Config.MIN # False
Config.MAX == Config.MAX #True
#与非枚举值结果总数不相等
Config.MAX == 1000 # False
枚举类型使用事项
- 枚举类不可实例化
- 枚举成员是可哈希的,可以在字典和集合中使用