【问题标题】:Metaclass conflict, multiple inheritance, and instance as parent元类冲突、多重继承、实例为父
【发布时间】:2011-11-20 22:49:41
【问题描述】:

我一直在玩 Python 的黑暗艺术,有一些我想帮助理解的东西。给定一个类Foo,下面是我尝试从它继承的一些方法:

  1. class A(Foo) — 工作,不出所料
  2. class B(Foo()) — 提供的作品 Foo 有一个合适的 __new__ 方法(我提供了)
  3. class C(Foo(), Foo) — 在与 B 相同的条件下工作
  4. class D(Foo, Foo()) — 给出著名的元类错误:

    回溯(最近一次通话最后一次):
    文件“test.py”,第 59 行,在
    D类(Foo,Foo()):
    TypeError:元类冲突:派生类的元类必须是(非严格) 其所有基础的元类的子类

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

【问题讨论】:

    标签: python inheritance metaclass


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • @Paul MRO 是“方法解析顺序”,即在查找方法/属性时检查类及其父类的顺序。我的直觉是,由于第一个父级中的方法“覆盖”了第二个父级中的方法,Python 将处理第二个,然后处理第一个。
    猜你喜欢
    • 2015-04-27
    • 2021-10-30
    • 2012-11-14
    • 2012-06-30
    • 1970-01-01
    • 2012-11-26
    • 2011-09-27
    • 2012-09-16
    相关资源
    最近更新 更多