元类冲突、多重继承、实例为父
Posted
技术标签:
【中文标题】元类冲突、多重继承、实例为父【英文标题】:Metaclass conflict, multiple inheritance, and instance as parent 【发布时间】:2011-11-20 22:49:41 【问题描述】:我一直在玩 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()): TypeError:元类冲突:派生类的元类必须是(非严格) 其所有基础的元类的子类
究竟是什么导致了这种冲突?当我从(Foo(), Foo)
(实例第一,类第二)继承时,它可以工作,但是当我从(Foo, Foo())
(类第一,实例第二)继承时,它不会。
【问题讨论】:
【参考方案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 将处理第二个,然后处理第一个。以上是关于元类冲突、多重继承、实例为父的主要内容,如果未能解决你的问题,请参考以下文章