> Hernan M. F
> Particularmente encuentro el ejemplo que presentas como poco elegante. Porque 
> en ese caso la clase C tiene una dependencia fija en el código al método F() 
> de la clase D la cual no puede ser modificada (bueno, si puede ser modificada 
> empleando settatr(), lo que hace a Python excelente desde mi punto de vista). 
> La cuestión es que se programa una vez, pero se modifica el código y se 
> revisa múltiples veces y en este caso el usuario de C tiene que leer todo el 
> código para darse cuenta de que cambiar si necesita reemplazar D.F por otra 
> cosa. Y finalmente si F es una función que no dependa de que argumentos 
> reciba D en el constructor, entonces no es necesario que sea miembro de la 
> clase D. Yo pondría tu ejemplo de la siguiente forma:
> 
> class C:
>  def __init__(self, f=None):
>    if f is None:
>      d = D()
>      f = d.f
> 
>    settatr(self, 'f', f)
> 
>  def f(self):
>    raise NotImplementedError()
> 

La dependencia la puedes quitar de forma similar a lo has puesto (inicializa 
con None, condicionalmente,
o como creas mas conveniente). Flexibiliza la firma usando kwargs, etc...

class C (B):
    def __init__(self, f_provider = D()):
       self._f_provider = f_provider
    def F(self):
       self._f_provider.F()

Mi respuesta anterior era prevenir el abuso de setattr cuando hay patrones de 
uso que son mucho
mas sencillos y prácticos.

Piensa en el caso de uso. Si inyectas vía setattr te impide que puedas ajustar 
luego el comportamiento.
Lo que se suele  necesitar en los casos reales es hacer algo antes y/o después 
de la invocación al
suministrador del servicio. Encima si inyectas F a B o C así, ¿cómo accede F a 
datos internos de B?

    …
    def F(self):
        hacer_algo_previo_con_self()
        self._f_provider.F( o_invocar_F_con_alguna_opción_especifica )
        hacer_otra_cosa_con_self_con_el_resultado_de_F()


> Esta variante le deja claro al usuario que solo con parametrizar la clase C 
> puede reemplazar la maquinaria externa que consume la clase. Finalmente 
> quiero decir (mi criterio nuevamente y el de algunas personas que asi lo 
> ponen en sus blogs) que la herencia multiple no es la forma de inyectar 
> comportamiento en una clase y que debe ser usada con mucho cuidado. Herencia 
> es herencia, una persona hereda de animal pero un navegador web no hereda de 
> conexión de red solo porque la use y la herencia lo pueda hacer parecer que 
> funciona.

Es la discusión de décadas y hay opiniones de todo tipo. No voy a entrar en 
ésta, a no ser que hablemos de casos concreto
de código, no tengo intención definir qué es ser.

Como dije en mi mensaje anterior lo formal en Python es usar abc. (Ver ejemplo 
de Chema en un mail posterior).


_______________________________________________
Python-es mailing list
Python-es@python.org
https://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Reply via email to