Python之子类自动注册

1,537 阅读2分钟

简介

  • 目标:子类继承基类后,能通过基类获取到所有的子类。
  • 意义:不需要子类执行注册操作,通过基类可以管理所有的子类。
  • 示例: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方法

参考链接