Uso las metaclases con cierta frecuencia, y son una herramienta extremadamente poderosa para tener en la caja de herramientas. A veces, su solución a un problema puede ser más elegante, con menos código, con ellos que sin ellos.
Lo que me resulta más frecuente al usar metaclases es el postprocesamiento de los atributos de clase durante la creación de la clase. Por ejemplo, establecer un atributo name
en los objetos en su caso (como la forma de la ORM de Django podría funcionar):
class AutonamingType(type):
def __init__(cls, name, bases, attrs):
for k,v in attrs.iteritems():
if getattr(v, '__autoname__', False):
v.name = k
class Autonamer(object):
__metaclass__ = AutonamingType
Si usted tiene esto como una herramienta, y está usando una clase que debe conocer su name
antes de que se puede do_something()
:
class Foo(object):
__autoname__ = True
def __init__(self, name=None):
self.name = name
def do_something(self):
if self.name is None:
raise ValueError('name is None')
# now, do something
Se puede hacer la diferencia en el resto de su código entre este:
class Bar(object):
myfoo1 = Foo('myfoo1')
myfoo2 = Foo('myfoo2')
myfoo3 = Foo('myfoo3')
y esto:
class Baaz(Autonamer):
myfoo1 = Foo()
myfoo2 = Foo()
myfoo3 = Foo()
reduciendo así la duplicación (y las posibilidades de que el nombre de la variable y el nombre asignado se salgan de sincronización).
Recuerdo que leí en un lugar como este sobre las metaclases, citado de manera muy vaga: "si tiene que preguntar para qué sirven, significa que no las va a necesitar". +1, pregunta interesante. –
No estoy seguro de que "no se pueda hacer de otra manera" es un criterio útil. Casi todo se puede hacer de muchas maneras diferentes, todo es cuestión de lo fácil/natural que es. –
Debería haber una, y preferiblemente solo una, forma obvia de hacerlo. :) –