Skip to main content

元类的有用基类

项目描述

元类是 Python 中一个非常强大的工具。您可以使用它们控制整个类创建过程。

然而,大多数时候,它们太强大了。该模块可帮助您使用元类的一些优点,而无需了解所有细节。它定义了一个基类SubclassInit。从这个类继承可以修改子类的创建过程。

初始化子类

元类的一个非常常见的用例是您只想在创建类后执行一些代码。这可以通过SubclassInit轻松完成 。您只需定义一个方法__init_subclass__,它被隐式视为@classmethod并将在您的类生成的每个子类之后调用。作为参数,它获取类的命名空间。一个例子是一个简单的子类注册:

class Register(SubclassInit):
    subclasses = []

    def __subclass_init__(cls, ns, **kwargs):
        super().__subclass_init__(ns, **kwargs)
        Register.subclasses.append(cls)

请注意如何添加关键字参数。这些是类定义行中给出的关键字参数,如下所示:

class Subclass(Base, spam="ham"):
    pass

不要忘记正确调用super()!其他类也可能想要初始化子类。这也是为什么你应该传递关键字参数,只取出你需要的那些。

初始化描述符

描述符是一种创建对象属性的强大技术,可以即时计算它们的值。属性是这种描述符的一个简单示例。这些描述符有一个共同的问题:他们不知道自己的名字。使用SubclassInit您可以将 __init_descriptor__方法添加到描述符,一旦类准备好并且描述符的名称已知,该方法就会被调用。

例如,我们可以定义一个使属性成为弱引用的描述符:

import weakref

class WeakAttribute:
    def __get__(self, instance, owner):
        return instance.__dict__[self.name]()

    def __set__(self, instance, value):
        instance.__dict__[self.name] = weakref.ref(value)

    def __init_descriptor__(self, owner, name):
        self.name = name

属性顺序

有时人们对在类中定义属性的顺序感兴趣。SubclassInit留下一个元组,其中所有属性的名称按照它们被定义为名为__attribute_order__的类属性的顺序排列 。请注意,Python 已经定义了一些类属性,例如__module__,其中一些也出现在这个元组中。

举个例子:

class AttributeOrder(SubclassInit):
    a = 1

    def b(self):
        pass

    c = 5

assert AttributeOrder.__attribute_order__ == \
    ('__module__', '__qualname__', 'a', 'b', 'c')

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

metaclass-1.3.tar.gz (2.7 kB 查看哈希)

已上传 source