元类的有用基类
metaclass的Python项目详细描述
元类是python中非常强大的工具。你可以控制 整个类的创建过程。
然而,大多数时候,它们太强大了。此模块有助于 使用元类的一些优点,而不必 去了解所有的细节。它定义了一个基类子类。 从这个类继承可以修改子类的创建 过程。
初始化子类
元类的一个非常常见的用例是您只想执行 创建类后的一些代码。这样做很容易 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')