class MyMeta(type):
def __new__(meta, cls, bases, attributes):
print 'MyMeta.__new__'
return type.__new__(meta, cls, bases, attributes)
def __init__(clsobj, cls, bases, attributes):
print 'MyMeta.__init__'
class MyClass(object):
__metaclass__ = MyMeta
foo = 'bar'
Otra forma de lograr el mismo resultado:
cls = "MyClass"
bases =()
attributes = {'foo': 'bar'}
MyClass = MyMeta(cls, bases, attributes)
MyMeta
es invocable, por lo que Python utilizará el método especial __call__
.
Python buscará __call__
en el MyMeta
's tipo (que es type
en nuestro caso)
"Para las clases de nuevo estilo, invocaciones implícitas de métodos especiales están sólo se garantiza que funcionen correctamente si se define en el tipo de un objeto, no en el diccionario de la instancia del objeto"
MyClass = MyMeta(...)
se interpreta como:
my_meta_type = type(MyMeta)
MyClass = my_meta_type.__call__(MyMeta, cls, bases, attributes)
Dentro de la type.__call__()
me imagino algo como esto:
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
MyMeta.__new__()
decidirá cómo se construye el MyClass
:
type.__new__(meta, cls, bases, attributes)
establecerá la metaclase correcta (que es MyMeta
) para MyClass
type(cls, bases, attributes)
configurará la metaclase predeterminada (que es tipo) para MyClass
Pero esa es la pregunta que estoy recibiendo: ¿por qué 'type' no devuelve el tipo correcto de objeto? Sé que tengo que usar el método '__new__' de la subclase, pero ¿cómo es eso diferente de usar' type'? –
¿Cómo se supone que el tipo sabe mágicamente qué tipo de objeto quieres que haga? –
bueno, porque yo lo digo. Pasé en nombre, bases y dict. ¿Qué otra información necesito para darle? –