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