Herencia múltiple en Python

written by uve 2 October 2010

Siguiendo un poquito con la herencia, Python nos permite realizar herencia múltiple. Es importante tener en cuenta que el método super invoca únicamente a la primera clase base. Supongamos las siguientes clases base:

class BaseA(object):
    def __init__(self, a):
        self.a = a
        print 'BaseA:', a

class BaseB(object):
    def __init__(self, b):
        self.b = b
        print 'BaseB:', b

¿Cómo realizamos una herencia múltiple? Muy sencillo:

class Hijo(BaseA, BaseB):
    pass

Si instanciamos la clase Hijo, sólo se ejecutará el constructor de la primera clase base:

>>> hijo = Hijo('hijo')
BaseA: hijo
>>>

Cada vez que llamamos a un método de la instancia, el funcionamiento es el siguiente:

  1. Se busca el método en la primera clase base
  2. Si se encuentra, se ejecuta; si no se encuentra, se busca en la siguiente clase base

Así que cuidado si las clases bases tienen métodos con el mismo nombre. Pero, ¿y si necesitamos llamar a ambos constructores porque cada uno agrega información a la clase? Es necesario hacerlo a mano:

class Hijo(BaseA, BaseB):
    def __init__(self, a, b):
        BaseA.__init__(self, a)
        BaseB.__init__(self, b)

De esta forma se invocan ambos constructores, cada cual con sus parámetros. Es importante observar, que la invocación al método, __init__ en este caso, también recibe el parámetro self. Esto se debe a que estamos invocando un método de instancia a través de su clase (es decir, el método no está ligado a una instancia). Con el resto de métodos pasa exactamente igual:

class BaseA(object):
    def __init__(self, a):
        self.a = a

    def foo(self):
        print self.a

class BaseB(object):
    def __init__(self, b):
        self.b = b

    def foo(self):
        print self.b

class Hijo(BaseA, BaseB):
    def __init__(self, a, b):
        BaseA.__init__(self, a)
        BaseB.__init__(self, b)

    def foo(self):
        BaseA.foo(self)
        BaseB.foo(self)

El resultado sería:

>>> hijo = Hijo('aaa', 'bbb')
>>> hijo.foo()
aaa
bbb

Tags

La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.