Python Language Metaclases basicas


Ejemplo

Cuando se llama a type con tres argumentos, se comporta como la clase (meta) que es y crea una nueva instancia, es decir. produce una nueva clase / tipo.

Dummy = type('OtherDummy', (), dict(x=1))
Dummy.__class__              # <type 'type'> 
Dummy().__class__.__class__  # <type 'type'> 

Es posible subclase type para crear una metaclase personalizado.

class mytype(type):
    def __init__(cls, name, bases, dict):
        # call the base initializer
        type.__init__(cls, name, bases, dict)

        # perform custom initialization...
        cls.__custom_attribute__ = 2

Ahora, tenemos una nueva metaclase mytype personalizada que se puede utilizar para crear clases de la misma manera que el type .

MyDummy = mytype('MyDummy', (), dict(x=2))
MyDummy.__class__              # <class '__main__.mytype'>
MyDummy().__class__.__class__  # <class '__main__.mytype'>
MyDummy.__custom_attribute__   # 2

Cuando creamos una nueva clase utilizando la palabra clave de class la metaclase se elige de forma predeterminada en función de las clases básicas.

>>> class Foo(object):
...     pass

>>> type(Foo)
type

En el ejemplo anterior, la única clase de base es el object por lo que nuestra metaclase será el tipo de object , que es el type . Es posible anular el valor predeterminado, sin embargo, depende de si usamos Python 2 o Python 3:

Python 2.x 2.7

Un atributo de nivel de clase especial __metaclass__ se puede usar para especificar la metaclase.

class MyDummy(object):
    __metaclass__ = mytype
type(MyDummy)  # <class '__main__.mytype'>
Python 3.x 3.0

Un argumento especial de palabra clave de metaclass especifica la metaclase.

class MyDummy(metaclass=mytype):
    pass
type(MyDummy)  # <class '__main__.mytype'>

Cualquier argumento de palabra clave (excepto metaclass ) en la declaración de clase se pasará a la metaclase. Así, la class MyDummy(metaclass=mytype, x=2) pasará x=2 como argumento de palabra clave al constructor mytype .

Lea esta descripción detallada de las meta-clases de python para más detalles.