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