> 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/