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