
Rolin Azmitia
PreguntaHe estado leyendo que las Metaclases (Metaclass) son como el top-mero-top en Python, que toda clase es en verdad una instancia de la Metaclase type (sí, se llama igual que la función que nos dice qué es una variable o por el estilo).
Sin embargo, luego de horas de leer, aún no tengo mucha idea de qué son en verdad las Metaclases, para qué se usan y cómo se usan.
¿Alguien puede ayudar porfavor? c:

David Toca
Veras, las clases en python son al final del dia objetos, eso significa que le puedes asociar atributos, por ejemplo
class Test: pass Test.name = 'some name' print(Test.name) # prints 'some name'
Todos los objectos tiene su tipo, el tipo de un objeto entero es
int
Test
type
test_object = Test() print(type(1)) # <class 'int'> print(type(test_object)) # <class 'Test'> print(type(Test)) # <class 'type'> print(type(type)) # <class 'type'>
Pero porque nos importa el tipo y porque esta relacionado a la metaclase? Hay dos implicaciones importantes:
1- A travez de type podemos crear clases de forma dinamica, en tiempo de ejecucion
2- Podemos modificar el tipo de una clase asignandole una metaclase propia
Ejemplos de Usos
1- Podriamos escribir el primer ejemplo de la siguiente forma:
# Como las clases son instancias de type , podemos generar clases en tiempo de ejecucion instanciando un type # tambien podemos agregar atributos y metodos Test = type('Test', (), {}) Test.name = 'some name' print(Test.name) # prints 'some name'
Tambien podemos hacer n for y crear 100 clases de forma dinamica, o dependiendo de ciertas condiciones podriamos crear o no una clase, etc, etc.
2- Podemos asignar una metaclase llamada meta que inyecte un metodo, pero solo si el metodo no existe en la clase actual
class Meta(type): def __init__(cls, name, bases, nmspc): super(Meta, cls).__init__(name, bases, nmspc) if not hasattr(cls, 'say'): print("inyecting {} with method say".format(cls)) cls.say = lambda self : "Hello inyected by meta class" class EmptyClass(object, metaclass=Meta): pass class Hello(object, metaclass=Meta): def say(self): return "Hello" empty = EmptyClass() # inyecting <class 'EmptyClass'> with method say hello = Hello() # print(empty.say()) # Hello inyected by meta class# hello print(hello.say()) # hello
En general, las metaclases nos dan el control sobre como se crean nuestras clases y nos permite inyectar o eliminar atributos o metodos o incluso restringir la creacion de objetos de esa clase.