枚举类的使用
    实际开发中,我们离不开定义常量,当我们需要定义常量时,其中一个办法是用大写变量通过整数来定义,例如月份。虽然这样做简单快捷,缺点是类型是 int ,并且仍然是变量。那有没有什么好的方法呢?这时候我们定义一个 class 类型,每个常量都是 class 里面唯一的实例。正好 Python 提供了 Enum 类来实现这个功能如下

    1. from enum import Enum
    2. Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
    3. # 遍历枚举类型
    4. for name, member in Month.__members__.items():
    5. print(name, '---------', member, '----------', member.value)

    其输出结果为

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

    上面我们使用Enum 来定义了一个枚举类
    上面的代码,我们创建了一个有关月份的枚举类型 Month ,这里要注意的是构造参数,第一个参数 Month 表示的是该枚举类的类名,第二个 tuple 参数,表示的是枚举类的值;当然,枚举类通过 members遍历它的所有成员的方法。
    注意的一点是 ,member.value是自动赋给成员的int类型的常量,默认是从 1 开始的。
    而且 Enum 的成员均为单例(Singleton),并且不可实例化,不可更改

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

    1. class Enum(metaclass=EnumMeta):
    2. """Generic enumeration.
    3. Derive from this class to define new enumerations.
    4. """

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

    1. class EnumMeta(type):
    2. """Metaclass for Enum"""
    3. @property
    4. def __members__(cls):
    5. """Returns a mapping of member name->value.
    6. This mapping lists all enum members, including aliases. Note that this
    7. is a read-only view of the internal mapping.
    8. """
    9. return MappingProxyType(cls._member_map_)

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