Python 枚举类源码解析

  • 2020 年 1 月 19 日
  • 笔记

1. EnumMeta

元类编程,生成类的类,可以动态生成类。 用法: type(name, bases, dict) name -> 类名: str bases -> 基类: tuple dict -> 属性: dict EnumMeta元类是用于生成Enum类,后续类都继承Enum类。

    class EnumMeta(type):          def __new__(metacls, cls, bases, classdict):              # member_type    枚举成员的类型              # first_enum        第一个继承的类型枚举类              member_type, first_enum = metacls._get_mixins_(bases)              .......
_get_mixins_方法
    @staticmethod      def _get_mixins_(bases):          """          返回用于创建枚举成员的类型,以及第一个继承的类型枚举类。          """          # 这里是Enum(metaclass=Enum)时用到的,bases=()          if not bases:              return object, Enum            # 继承自Enum类的子类,由以下方法判断          member_type = first_enum = None          for base in bases:              if  (base is not Enum and                      issubclass(base, Enum) and                      base._member_names_):                  raise TypeError("Cannot extend enumerations")          # base is now the last base in bases          if not issubclass(base, Enum):              raise TypeError("new enumerations must be created as "                      "`ClassName([mixin_type,] enum_type)`")            # get correct mix-in type (either mix-in type of Enum subclass, or          # first base if last base is Enum)          if not issubclass(bases[0], Enum):              member_type = bases[0]     # first data type              first_enum = bases[-1]  # enum type          else:              for base in bases[0].__mro__:                  # most common: (IntEnum, int, Enum, object)                  # possible:    (<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>,                  #               <class 'int'>, <Enum 'Enum'>,                  #               <class 'object'>)                  if issubclass(base, Enum):                      if first_enum is None:                          first_enum = base                  else:                      if member_type is None:                          member_type = base            return member_type, first_enum