Esta receta incluye la implementación “comentada” de una metaclase Python para conseguir que el constructor de la superclase se invoque automáticamente.

Introducción

Para una mejor comprensión y máximo aprovechamiento, se recomienda al lector no iniciado en las metaclases, leer la receta Ahí va la virgen! Metaclases! antes de proceder con esta.

Invocación automática del “constructor” de la superclase

Cuando empezaste con Python quizá te sorprendió que cuando heredas una clase y sobrecargas el método __init__, no se invoque al __init__ de su superclase. Es decir:

>>> class A(object):
...    def __init__(self):
...       print 'init A'
...
>>> class B(A):
...    def __init__(self):
...       print 'init B'
...
>>> b = B()
init B

Pues bien, la siguiente metaclase permite que al crear una instancia de B, se invoque también el método __init__ de A de forma automática:

class AutoSuper(type):
   def __call__(cls, *args, **kw):
      obj = type.__call__(cls, *args, **kw)
      for i in cls.__bases__:
          i.__init__(obj, *args, **kw)
      return obj

Si ahora pruebas el ejemplo anterior, haciendo que A utilice la metaclase AutoSuper:

>>> class A(object):
...    __metaclass__ = AutoSuper
...    def __init__(self):
...       print 'init A'
...
>>> class B(A):
...    def __init__(self):
...       print 'init B'
...
>>> b = B()
init B
init A

Señalar que esta solución no es transitiva. La metaclase hace que se invoquen los __init__ de las superclases de esa clase. Es decir, sólo las superclases inmediatas, no se invocan los __init__ de ancestros indirectos.



blog comments powered by Disqus