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

ahu*_*igo 1 python metaclass python-3.x

为什么在下面的代码中带有对象基的元类会引发元类冲突异常?

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

class M_A(object): pass
class A(object, metaclass = M_A): pass
Run Code Online (Sandbox Code Playgroud)

另一个代码也是如此:

class M_A(list): pass
class A(object, metaclass = M_A): pass
Run Code Online (Sandbox Code Playgroud)

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

A = M_A.__new__(M_A, 'A', (object,), {})
Run Code Online (Sandbox Code Playgroud)

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

Ara*_*Fey 5

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

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

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

  • “派生类A.
  • “派生类的元类AM_A
  • A的基类是object,因此“其所有基类的元类”type- 因为typeobject的元类。

这就是问题所在—— object's 元类是type,但是A's 元类是M_A。由于M_A不是 的子类type,因此 python 不知道要使用哪个元类A并抛出错误。


要解决此问题,请将 的父类更改M_Atype

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

# no errors thrown
Run Code Online (Sandbox Code Playgroud)