metaclass冲突,多重继承和实例作为父类
我最近在研究Python,遇到了一些问题想请教一下。给定一个类Foo
,我尝试了几种从它继承的方式:
class A(Foo)
— 这个方法可以正常工作,没什么意外的。class B(Foo())
— 这个也能工作,只要Foo
有一个合适的__new__
方法(我提供了这个方法)。class C(Foo(), Foo)
— 这个也能工作,条件和B
一样。class D(Foo, Foo())
— 这个就出错了,出现了著名的元类错误:错误追踪(最近的调用在最前面):
文件 "test.py",第59行,
类 D(Foo, Foo()):
类型错误:元类冲突:派生类的元类必须是所有基类元类的(非严格)子类。
到底是什么导致了这个冲突呢?当我从(Foo(), Foo)
(先实例化,再类)继承时是可以的,但当我从(Foo, Foo())
(先类,再实例化)继承时就不行了。
1 个回答
5
当你“从一个实例继承”时,其实是在用一种奇怪的方式使用元类。通常,类对象是 type
的实例。在上面提到的 B 类中,它是从一个 Foo
的实例继承的。如果你用 Foo
作为元类来定义一个类,然后从这个类继承,结果就是这样。
我猜测这里发生的事情是,Python 正在反向处理基类的顺序。
C 类之所以能工作,是因为第一个被处理的父类是 Foo
,而它的类是 type
。这意味着 D 的元类必须是 type
或者它的某个子类。接着处理 Foo()
,它的类是 Foo
,而 Foo
是 type
的子类,所以一切正常。
D 类失败的原因是,第一个被处理的父类是 Foo()
,这就要求 D 的元类必须是 Foo
(或它的子类)。然后 Foo
被处理,它的类 type
不是 Foo
的子类。
这只是我的猜测,但你可以查查 Python 的元类文档,看看当你从两个不同元类的类中多重继承时,是否需要将它们按特定顺序排列,前提是这些元类之间有子类关系。