[Python-es] herencia multiple comportamiento con diferentes argumentos

Chema Cortes pych3m4 en gmail.com
Lun Ago 13 04:08:53 EDT 2018


El lun., 13 ago. 2018 a las 8:02, AGTUGO (<agtugo en gmail.com>) escribió:

> Estimada Lista de Python en español:
>
> Repasando un poco los conceptos de herencia multiple ya que no la uso
> mucho no recuerdo el porque del siguiente comportamiento, no entiendo
> porque paso por el iniciador de Second. De antemano muchas gracias. La idea
> de llamar los init de las clases Third y Second es pasarle argumentos
> diferentes y no tener que modificar Second y Third con **kwargs como
> argumento.
>
> class First(object):
>     def __init__(self):
>         print("first")
>
> class Second(First):
>     def __init__(self):
>         super(Second,self).__init__()
>         print("second")
>
> class Third(First):
>     def __init__(self):
>         super(Third,self).__init__()
>         print("third")
>
> class Fourth(Third,Second):
>     def __init__(self):
>         Third.__init__(self)
> #       Second.__init__(self)
>         print("Forth")
>
> print(First.__mro__)
> print(Second.__mro__)
> print(Third.__mro__)
> print(Fourth.__mro__)
>
> #//root = tk.Tk()
> #//app = Window(root)
> #//root.mainloop()
>
> nieto = Fourth()
>
> _________
>
> Salida:
>
> (<class '__main__.First'>, <class 'object'>)
> (<class '__main__.Second'>, <class '__main__.First'>, <class 'object'>)
> (<class '__main__.Third'>, <class '__main__.First'>, <class 'object'>)
> (<class '__main__.Fourth'>, <class '__main__.Third'>, <class '__main__.Second'>, <class '__main__.First'>, <class 'object'>)
> first
> second
> third
> Forth
>
> Siguiendo los pasos de la ejecución:

- Se crea una instancia de Fourth
- En la inicialización, se "fuerza" la ejecución del método __init__ en
Third
- En el método __init__ de Third, se invoca el método __init__ del
super(Third, self)

¿Quién es "super" aquí? Como 'self' es una instanacia de Fourth, se usa su
MRO: (Fourth, Third, Second, First, object), o sea, super es el siguiente a
Third en la secuencia, que sería Second.

- Se invoca el método __init__ de Second

El problema que se te plantea se conoce por "herencia múltiple
colaborativa". Para que funcione, los métodos invocados han de aceptar
cualquier número de argumentos, ignorando aquellos que no vaya a usar.

Lamentablemente, la herencia múltiple se suele usar más como "mixin" para
encadenar interfaces. Este tipo de uso no debería tener "inicializadores",
o bien usar una estructura de datos común que vendría a ser algo similar a
los argumentos **kwargs de la herencia múltiple colaborativa.

Mi consejo es que siempre uses **kwargs si piensas hacer interfaces que se
combinen por herencia múltiple.

-- 
Hyperreals *R  "Quarks, bits y otras criaturas infinitesimales":
http://ch3m4.org/blog
Buscador Python Hispano: http://ch3m4.org/python-es
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20180813/f5c329d4/attachment.html>


Más información sobre la lista de distribución Python-es