4 道练习题·预计 30 分钟·做对一题解锁下一段
这一节学的是 枚举类(Enum)——一种用来 代替魔法常量 的语法工具。
Enum 基本用法@unique / auto()== / is / IntEnum实际开发里,我们经常会遇到「几个固定的、有限的取值」这种场景:
最朴素的写法是用一组大写常量:
JAN = 1
FEB = 2
MAR = 3
# ...
NOV = 11
DEC = 12简单快捷,但有三个缺点:
JAN 只是一个 int,谁都可以拿别的整数来冒充:def show_month(m),调用方传进来 m = 99,函数也没办法知道这是不是一个合法的月份。JAN = 100 也不会报错。更好的做法是 定义一个 class,每个常量都是 class 里唯一的实例。
Python 标准库的 enum 模块就是干这个的。看看效果:
from enum import Enum
class Month(Enum):
JAN = 1
FEB = 2
MAR = 3
# ...
DEC = 12
print(Month.JAN) # Month.JAN
print(Month.JAN.name) # 'JAN'
print(Month.JAN.value) # 1跟普通常量比,Enum 的好处:
Month.JAN 的类型就是 Month,传错参数立刻看出来Month.JAN = 999 会直接报错Month() 不会创造新成员,所有成员都是 单例for m in Month: ... 直接拿到所有成员
Enum的成员均为 单例(Singleton),并且 不可实例化、不可更改。
最常见的写法是 继承 Enum 类:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3Color 本身是一个 类,Color.RED / Color.GREEN / Color.BLUE 是它的三个 成员。
print(Color.RED) # Color.RED ← 默认 repr
print(Color.RED.name) # 'RED' ← 成员名
print(Color.RED.value) # 1 ← 对应的值记住两个属性:
.name —— 成员的 名字(字符串).value —— 成员的 值(任意类型)Enum 是可迭代的:
for c in Color:
print(c.name, c.value)输出:
RED 1
GREEN 2
BLUE 3
也可以用 __members__ 拿到一个 有序映射(包含别名):
for name, member in Color.__members__.items():
print(name, '->', member, '->', member.value)不写 class,直接用 Enum(...) 函数:
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
print(Month.Jan) # Month.Jan
print(Month.Jan.value) # 1,从 1 开始自动分配第一个参数是类名,第二个参数是成员名的可迭代对象。这种写法适合「成员只是一组名字、不在乎具体的值」的场景。
推荐 优先用 class 写法——明确、可读、IDE 提示更友好。函数式写法只在需要动态生成 Enum 时才用。
请用 from···import 从 enum 模块导入 Enum,然后:
Enum 的类 Color,包含三个成员:
RED = 1GREEN = 2BLUE = 3print(Color.RED)输出应该是:
Color.RED
提示:直接
类名.成员名这种格式。