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