Otra vez la herencia múltiple
Alexis Roda
alexis.roda.villalonga en gmail.com
Mie Jul 23 18:20:26 CEST 2008
En/na Beni ha escrit:
> Leyendo lo que me habeis pasado y pensando un poco...
>
> supongo que como parece que funciona python, la signatura de los métodos
> tiene que ser igual. Pero no veo el por que no tener constructores con
> distintos tipos de parámetros. Java los usa continuamente. Es más, son
> objetos distintos que tienen sus propias propiedades y métodos. Y si heredo
> de ellos necesitaré algún método para poder llamarlos con los parámetros que
> yo crea necesarios en el hijo.
Para decidir que método invocar Java compara el número y tipo de los
argumentos utilizados en la llamada con los argumentos formales (número
y tipo) de los métodos homónimos y a partir de ciertas reglas escoge el
que mejor se ajusta. En python el tipo de los argumentos de una
función/método no se declara, por tanto este mecanismo no es aplicable
directamente.
En python es posible conseguir un efecto parecido utilizando *args y
**kw y programando la función/método de forma que se comporte de manera
diferente en función de los argumentos recibidos.
> Si no me equivoco (no domino mucho el inglés) parece que super te devuelve
> el tipo de una clase para llamar al método. Este tipo pude ser A, B, C
> dependiendo de la definición de la misma. Por tanto, como comentaba Alexis,
> deben tener la misma signatura.
No me explique bien. Quería decir que tu ejemplo no funcionaría por este
motivo. Como bien dices, super() se limita a ofrecer un mecanismo para
localizar el método y no sabe nada sobre los parámetros utilizados en la
llamada.
La restricción no es tan fuerte. Más que signaturas idénticas deben
tener signaturas compatibles. Esto puedes conseguirlo con *args, **kw
y/o argumentos con valores por defecto.
class A(object):
def __init__(self, nombre, *args):
print nombre
super(A, self).__init__(nombre, *args)
class B(object):
def __init__(self, nombre, apellidos):
print nombre, apellidos
super(B, self).__init__(nombre, apellidos)
class C(A, B):
def __init__(self):
super(C, self).__init__("hola", "adios")
class D(B, A):
def __init__(self):
super(D, self).__init__("hola", "adios")
print "C (A, B) - A(nombre) - B(nombre, apellidos) >",
c = C()
print "D (B, A) - A(nombre) - B(nombre, apellidos) >",
d = D()
Aunque en mi opinión es un truco muy sucio, con más inconvenientes que
ventajas.
> Por tanto para llamar a cada constructor necesitaré hacerlo de la forma
> antes comentada.
> class C(A, B):
> def __init__():
> A.__init__(self, "hola")
> B.__init__(self, "hola", "adios")
>
> ¿Sería correcto?
Funciona, sí y si A y B son clases dispares probablemente sea la mejor
opción.
Saludos
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es