为什么带有对象库的元类会引发元类冲突?

时间:2017-10-01 09:53:32

标签: python python-3.x metaclass

为什么在下面的代码中使用对象库的元类会引发元类冲突异常?

  

“元类冲突:派生类的元类必须是其所有基类的元类的(非严格)子类”

class M_A(object): pass
class A(object, metaclass = M_A): pass

另一个代码也是如此:

class M_A(list): pass
class A(object, metaclass = M_A): pass

我知道cpython会将上面的代码解释为:

A = M_A.__new__(M_A, 'A', (object,), {})

令我困惑的是A的基类是 object ,而任何类都是 object 的子类。这个错误很奇怪。 我怎么了?

1 个答案:

答案 0 :(得分:3)

让我们仔细看看这条错误消息:

  

元类冲突:派生类的元类必须是其所有基类的元类的(非严格)子类

这有点令人困惑,所以让我们来看看它是什么:

  • "派生类" A
  • 派生类" A"元类是M_A
  • A的基类为object,因此"其所有基础的元类" type - 因为typeobject的元类。

这就是问题 - object的元类是type,但A的元类是M_A。由于M_A不是type的子类,因此python不知道要用于A的哪个元类并引发错误。

要解决此问题,请将M_A的父类更改为type

class M_A(type): pass
class A(object, metaclass = M_A): pass

# no errors thrown