我的问题是受这个问题启发而来。
问题在于三级类模型——终止类(第三级)应该只存储在注册表中,但第二级正在干扰并且也已经存储了,因为它们是第一级的子类。
我想通过使用元类来摆脱第一级类。通过这种方式,只剩下两个类级别——每个设置组的基类和它们的子类——从相应的基类继承的各种设置类。元类充当类工厂——它应该创建具有所需方法的基类,并且不应在继承树中显示。
但我的想法行不通,因为似乎__init_subclass__
方法(链接到方法)没有从元类复制到构造的类中。与我预期的不同的是,__init__
方法可以正常工作。
代码片段 №1. 模型的基本框架:
class Meta_Parent(type):
pass
class Parent_One(metaclass=Meta_Parent):
pass
class Child_A(Parent_One):
pass
class Child_B(Parent_One):
pass
class Child_C(Parent_One):
pass
print(Parent_One.__subclasses__())
输出:
[<class '__main__.Child_A'>, <class '__main__.Child_B'>, <class '__main__.Child_C'>]
我想要在上述模型的子类化过程中添加功能,因此我重新定义了type
内置的__init_subclass__
如下:
代码片段 № 2.
class Meta_Parent(type):
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
print(cls)
在我看来,现在每一个由Meta_Parent元类(例如,Parent_One)构建的新类都应该有__init_subclass__
方法,并且在每个类从这个新类继承时打印出子类的名称,但实际上它没有打印任何东西。也就是说,在发生继承时我的__init_subclass__
方法没有被调用。
如果直接继承自Meta_Parent元类,则会起作用:
代码片段 №3.
class Meta_Parent(type):
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
print(cls)
class Child_A(Meta_Parent):
pass
class Child_B(Meta_Parent):
pass
class Child_C(Meta_Parent):
pass
输出:
<class '__main__.Child_A'>
<class '__main__.Child_B'>
<class '__main__.Child_C'>
这里没有什么奇怪的地方,__init_subclass__
就是为了这个目的而创建的。
我一度认为双下划线方法只属于元类,并且不会传递到新构建的类中,但后来尝试了 __init__
方法,它就像我一开始期望的那样工作 - 看起来每个元类的类都复制了对 __init__
的链接。
代码片段编号 4。
class Meta_Parent(type):
def __init__(cls, name, base, dct):
super().__init__(name, base, dct)
print(cls)
输出:
<class '__main__.Parent_One'>
<class '__main__.Child_A'>
<class '__main__.Child_B'>
<class '__main__.Child_C'>
问题:
__init__
为何可行,而__init_subclass__
则不行?- 通过使用元类,实现我的想法是否可行?