Metaclase no se llama en subclases

Aquí hay una sesión de python.

>>> class Z(type): def __new__(cls, name, bases, attrs): print cls print name return type(name, bases, attrs) ... >>> class Y(object): __metaclass__ = Z ...  Y >>> class X(Y): ... pass ... >>> class W(Y): ... __metaclass__ = Z ...  W >>> 

Después de definir la clase XI, espero que se llame a Z._new__, e imprima las dos líneas, lo que no está sucediendo (¿se heredan las metaclases ?)

El problema es que el argumento cls (que es el objeto de metaclase) no se transmite cuando llama al type , por lo tanto, el objeto de clase Y que se crea y devuelve no tiene ninguna referencia a la metaclase Z

Si reemplaza la última línea en __new__ con

 return super(Z, cls).__new__(cls, name, bases, attrs) 

entonces funciona. Tenga en cuenta que aunque cls se usa en super , también tenemos que proporcionar cls como argumento, ya que super here devuelve un método independiente (consulte aquí para obtener más información).

Como alternativa a usar super one podríamos usar:

  return type.__new__(cls, name, bases, attrs) 

Lo importante es que damos cls (nuestro objeto de metaclase Z ) al método de __new__ . El type(name, bases, attrs) formulario más corto type(name, bases, attrs) en el propio type para el argumento cls , que por supuesto es incorrecto. Este error es similar a llamar a un método de instancia con un argumento self equivocado.

Prefiero usar super , ya que este es mejor estilo.