简介
目标:子类继承基类后,能通过基类获取到所有的子类。
意义:不需要子类执行注册操作,通过基类可以管理所有的子类。
示例:SQLAlchemy的数据库管理,继承基类将会自动被migration发现。
实现
构建元类
class BaseMetaClass(type):
"""元类
元类控制类的创建,创建类时将会执行元类的__new__方法。
基于这个机制,可以在new的过程中将子类注册到BaseMetaClass的类属性中。
"""
record_cls = []
def __new__(mcs, name, bases, attrs):
new_cls = type.__new__(mcs, name, bases, attrs)
# 如果子类名为Base,不会注册
if name not in ["Base"]:
BaseMetaClass.record_cls.append(new_cls)
return new_cls
构建基类
class Base(object, metaclass=BaseMetaClass):
pass
构建子类
class MyClass(Base):
pass
知识延伸
通过metaclass参数可以控制类的创建行为
class Book(BaseBook, metaclass=BookMetaClass)
诸如此类的方式,可以控制Book这个类的创建行为。在BookMetaClass.new方法中编写具体的逻辑,在执行到上述代码行时将会自动执行元类的new方法。
创建类的本质是创建type对象
class Book(BaseBook)
的等价写法是Book = type("Book")
。
因此创建Book类的过程和创建Book对象的过程是相似的,不同的是创建Book类的过程执行“元类BookMetaClass的new”,创建Book对象的过程执行“Book自己的new和Book自己的init”。
创建类、创建类对象的具体流程如下:
- 启动程序,执行到class Book代码行,此时创建类,执行该类的元类new方法
- 执行到Book()代码行,此时创建类对象,执行该类自己的new方法,该方法返回类对象
- 第二步的new方法在返回类对象时,自动callback该类自己的init方法