专项练习 · 8 分钟阅读

Python 枚举练习:名称、值与查找

枚举给状态、颜色、方向这类概念一组固定名称。成员是真实对象,而不是散落的字符串,因此比较和查找都更明确。

定义一组封闭成员

继承 Enum,并给名称赋值。类体定义可用成员。按惯例成员名大写,保存的值可以是字符串、数字或其他可哈希对象。

from enum import Enum
class Status(Enum):
    OPEN = "open"
    CLOSED = "closed"
print(Status.OPEN.value)

名称与稳定值

名称和值不是一回事

成员是枚举对象。name 是类中使用的标识符,value 是赋给它的数据。直接打印成员会显示限定名称,而 .value 返回底层数据。

from enum import Enum
class Color(Enum):
    RED = "red"
member = Color.RED
print(member.name)
print(member.value)
print(member)

同一个成员的三种视图

按值或按名称查找

用值调用枚举会返回匹配成员,没有匹配时抛出 ValueError。方括号查找使用成员名,找不到时抛出 KeyError。根据手上的输入选择查找方式。

from enum import Enum
class Color(Enum):
    RED = "red"
    GREEN = "green"
print(Color("green"))
print(Color["RED"])

两个方向的查找

按定义顺序遍历

遍历枚举会按定义顺序产生成员。这适合构建菜单或校验选项集合。普通遍历会跳过别名,除非直接查看成员映射。

from enum import Enum
class Size(Enum):
    SMALL = 1
    MEDIUM = 2
    LARGE = 3
print([item.name for item in Size])

保留定义顺序

用 auto 生成值

当具体数字不重要时,auto 可以让 Python 自动赋值。这样源码可以专注于成员名称。不要把自动生成的数字当作稳定的外部格式。

from enum import Enum, auto
class Step(Enum):
    START = auto()
    FINISH = auto()
print(Step.START.value)
print(Step.FINISH.value)

让 Python 给成员编号

你的练习清单

常见问题

枚举成员等于它的值吗?

不等于。Color.RED 与字符串 red 不相等。需要底层值时比较 Color.RED.value。

两个名称可以共享一个值吗?

可以。第二个名称会成为第一个成员的别名,普通遍历会跳过别名。

应该把枚举值存进数据库吗?

应保存有意设计的稳定值,而不是成员对象。以后修改值可能破坏已存数据,所以要把值当成格式的一部分。

练习枚举

12 道题,覆盖成员、名称与值、查找、遍历和 auto。

打开练习

继续阅读: