元类冲突,多重继承和实例作为父级

时间:2011-09-20 09:57:29

标签: python inheritance metaclass

我一直在搞乱Python的黑暗艺术,我想帮助理解。给定一个类Foo,这是我尝试从中继承的一些方法:

  1. class A(Foo) - 工作,毫无疑问
  2. class B(Foo()) - 提供的作品Foo有适当的__new__方法(我提供)
  3. class C(Foo(), Foo) - 在与B
  4. 相同的条件下工作
  5. class D(Foo, Foo()) - 给出了着名的元类错误:
      

    追踪(最近的呼叫最后):
      文件“test.py”,第59行,在   D级(Foo,Foo()):
      TypeError:元类冲突:派生类的元类必须是(非严格)   所有基础的元类的子类

  6.   

    究竟是什么导致了这场冲突?当我继承(Foo(), Foo)(实例优先,第二类)时,它可以工作,但是当我从(Foo, Foo())(第一个类,实例第二个)继承时,它不会。

1 个答案:

答案 0 :(得分:5)

当你“从实例中固有”时,你真正在做的是一种使用元类的奇怪方式。通常,类对象是type的实例。在上面的B类的情况下,它继承自Foo的实例。如果您定义了一个以Foo作为其元类的类,然后从该类继承,那么这正是会发生的。

所以我对这里发生的事情的猜测是Python正在以反向MRO顺序处理基类。

C类有效,因为要处理的第一个父类是Foo,其类为type。这意味着D的元类必须是type或其某些子类。然后处理Foo(),其类为Foo,这是type的子类,所以一切都很好。

D类失败,因为要处理的第一个父类是Foo(),它设置了一个约束,即D具有Foo(或子类)的元类。然后Foo出现,其typeFoo的子类。

这是一个完整的猜测,但您可以尝试查看元类的Python文档是否需要从两个具有不同元类的类中继承,其中涉及的元类具有子类型关系,您将它们按特定顺序放置