小白学 Python
AI 编程指南
© 2026 小白学 Python · 基于 walter201230/Python 教程
课程目录关于本站联系方式隐私政策GitHub

全部课程

  1. 00为什么学 Python
  2. 01Python 安装与第一个程序
  3. 02基本数据类型与变量
  4. 03List 与 Tuple
  5. 04Dict 与 Set
  6. 05条件与循环
  7. 06函数
  8. 07迭代
  9. 08面向对象
  10. 09模块
  11. 10魔法方法
  12. 11枚举类
  13. 12元类 metaclass
  14. 13线程与进程
  15. 14正则表达式
  16. 15闭包
  17. 16装饰器
  18. 17代码可读性
  19. 18pathlib:现代化路径处理
  20. 19异常处理
  21. 20dataclass
  22. 21上下文管理器(with)
  23. 22async / await
  24. 23pyproject.toml + uv
  25. 24ruff:一站式代码检查
  26. 25pytest:测试框架
  27. 26日志 logging
  28. 27打包发布到 PyPI
  29. 28学完之后
Python 环境加载中…

枚举类

4 道练习题·预计 40 分钟·做对一题解锁下一段

完整通读本章 →

教学 01 / 06· 已读

前言

2019年10月14日16:59:38 看了一下,还有五个章节就修改完基础部分了。

干就完事了。

目录

这一篇的目录如下:

  • 一、枚举类的使用
  • 二、Enum 的源码
  • 三、自定义类型的枚举
  • 四、枚举的比较
教学 02 / 06· 已读

一、枚举类的使用

实际开发中,我们离不开定义常量,当我们需要定义常量时,其中一个办法是用大写变量通过整数来定义,例如月份:

Python· 结合前文阅读
JAN = 1
FEB = 2
MAR = 3
...
NOV = 11
DEC = 12

当然这样做简单快捷,缺点是类型是 int ,并且仍然是变量。

那有没有什么好的方法呢?

这时候我们定义一个 class 类型,每个常量都是 class 里面唯一的实例。

正好 Python 提供了 Enum 类来实现这个功能如下:

Python· 结合前文阅读
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

# 遍历枚举类型
for name, member in Month.__members__.items():
    print(name, '---------', member, '----------', member.value)

# 直接引用一个常量
print('\n', Month.Jan)

输出的结果如下:

文本
Jan --------- Month.Jan --------- 1
Feb --------- Month.Feb --------- 2
Mar --------- Month.Mar --------- 3
Apr --------- Month.Apr --------- 4
May --------- Month.May --------- 5
Jun --------- Month.Jun --------- 6
Jul --------- Month.Jul --------- 7
Aug --------- Month.Aug --------- 8
Sep --------- Month.Sep --------- 9
Oct --------- Month.Oct --------- 10
Nov --------- Month.Nov --------- 11
Dec --------- Month.Dec --------- 12

 Month.Jan

我们使用 Enum 来定义了一个枚举类。

上面的代码,我们创建了一个有关月份的枚举类型 Month ,这里要注意的是构造参数,第一个参数 Month 表示的是该枚举类的类名,第二个 tuple 参数,表示的是枚举类的值;当然,枚举类通过 __members__ 遍历它的所有成员的方法。

注意的一点是 , member.value 是自动赋给成员的 int 类型的常量,默认是从 1 开始的。

而且 Enum 的成员均为单例(Singleton),并且不可实例化,不可更改

状态的名字和状态的值

我们想给学习任务标上「待学习」或「已完成」。用枚举把允许的状态列清楚,再分开观察成员名和值:

Python· 可在网页运行
from enum import Enum


class StudyState(Enum):
    TODO = '待学习'
    DONE = '已完成'


print(StudyState.TODO.name)
print(StudyState.TODO.value)
print(StudyState('已完成') is StudyState.DONE)

输出:

文本
TODO
待学习
True

TODO 是成员的名称,'待学习' 是这里给它安排的值。StudyState('已完成') 按值寻找成员,不是在创建一个任意内容的新状态。

自己试试一个没有定义过的值,观察 ValueError;再比较 StudyState.TODO == '待学习',结果为 False,因为这里的普通 Enum 成员和它的字符串值不是同一个东西。不同枚举类型的比较规则要看对应类型,不从这个例子推导所有枚举都和字符串一样。

本章的源码分析可以帮助理解实现,但完成一个状态选择的小需求后再回看,通常更容易知道自己在追哪一段逻辑。

教学 03 / 06

二、Enum 的源码

通过上面的实例可以知道通过 __members__ 可以遍历枚举类的所有成员。

那有没有想过为什么呢?

当你看到那段代码的时候,有没有想过为什么通过 __members__ 就能遍历枚举类型的所有成员出来?

我们可以先来大致看看 Enum 的源码是如何实现的;

Enum 在模块 enum.py 中,先来看看 Enum 类的片段

Python· 结合前文阅读
class Enum(metaclass=EnumMeta):
    """Generic enumeration.
    Derive from this class to define new enumerations.
    """

可以看到,Enum 是继承元类 EnumMeta 的;再看看 EnumMeta 的相关片段

Python· 结合前文阅读
class EnumMeta(type):
    """Metaclass for Enum"""
    @property
    def __members__(cls):
        """Returns a mapping of member name->value.
        This mapping lists all enum members, including aliases. Note that this
        is a read-only view of the internal mapping.
        """
        return MappingProxyType(cls._member_map_)

首先 __members__ 方法返回的是一个包含一个 Dict 既 Map 的 MappingProxyType,并且通过 @property 将方法 __members__(cls) 的访问方式改变为了变量的的形式,那么就可以直接通过 __members__ 来进行访问了

练习 1 / 4·定义一个 Color 枚举类题目有问题?

请用 from ... import 从 enum 模块导入 Enum,然后:

  1. 定义一个继承 Enum 的类 Color,包含三个成员:
    • RED = 1
    • GREEN = 2
    • BLUE = 3
  2. print(Color.RED)

输出应该是:

文本
Color.RED

提示:直接 print 一个 Enum 成员,默认会打出 类名.成员名 这种格式。

main.py
可编辑
🔒做对当前题解锁下一段 ·0/4

推荐一个,全网最全最友好的中文 AI 编程指南: coding.stormzhang.ai

← 上一章10 · 魔法方法
枚举类
下一章 →12 · 元类 metaclass
本章目录

枚举类

  1. 教学 01前言
  2. 教学 02一、枚举类的使用
  3. 教学 03二、Enum 的源码
  4. 练习 1定义一个 Color 枚举类
  5. 练习 2 🔒访问 .name 和 .value
  6. 练习 3 🔒遍历 Enum 的所有成员
  7. 教学 04 🔒三、自定义类型、@unique、auto()
  8. 练习 4 🔒用 auto() 自动分配值
  9. 教学 05 🔒三、自定义类型的枚举
  10. 教学 06 🔒四、枚举的比较

学习目录