A ese respecto, hay un detalle que me parece interesante comentar. Quizá sea un detalle que parezca irrelevante, pero creo que es interesante comprender bien como funciona internamente el api de reflectividad en python si uno no se quiere topar con errores a los que no se les es capaz de encontrar el sentido. Y lo digo por experiencia ;-)
En python, cuando se le pide un atributo/método a un objeto, en realidad el método __getattr__ es el encargado de buscarlo, bien en el propio objeto instancia o en su jerarquía de clases. Este método devuelve el atributo (o método) si lo encuentra, o lanza una excepción AttributeError. Para evitar llamadas recursivas y provocar errores en caso de no encontrarse, el modelo reflectivo presenta una asimetría entre __getattr__ y __setattr__: * __getattr__ no se llama si el atributo no se encuentra por las vías convencionales * para tener control total sobre la operación es necesario recurrir al método __getattribute__ y así evitar esos problemas de recursividad infinita; este método siempre debe invocar el método de la clase base. No sé cual es el problema concreto que necesita resolve Ander, pero esta es mi receta para tener control total en entornos con uso extensivo de la reflectividad unido a jerárquias complejas de clases: obj.__dict__[’__setattr__’] = MethodType(set_func, obj, obj.__class__) obj.__dict__[’__getattribute__’] = MethodType(get_func, obj, obj.__class__) Puede parece una manera un tanto enrevesada en lugar de usar el simple built-in setattr(), pero hay situaciones que exigen tal tratamiento. Al menos python lo permite, tratar de hacer eso con java.lang.reflection xD 2013/10/21 Juan BC <jbc.deve...@gmail.com>: > setattr(b, "mi_servicio", a.mi_servicio) > > El día 21 de octubre de 2013 11:30, Yeiniel Suárez Sosa > <yein...@uclv.cu> escribió: >> Hola >> >> como lo que pregunta es si la práctica está extendida, le voy a responder >> con mi práctica. >> Normalmente no creo un decorador para esto. Supongamos que tengo una clase A >> que >> ofrece un servicio mi_servicio (un método) y una clase B que desea usar el >> servicio >> que ofrece A (no es una herencia, sino una composición). En este caso yo en >> la clase B escribo >> una declaración de la misma función con el mismo nombre, los mismos >> parámetros, las mismas >> anotaciones (si usas Python 3.x) solo que le pongo en el cuerpo "raise >> NotImplementedError()" y en la >> documentación indico que debe ser un método compatible con "A.mi_servicio" >> fijense que digo compatible, aqui dejo >> abierta la posibilidad para muchas cosas. >> De esta forma indico que B consume un servicio pero que no lo implementa >> esta clase. A la hora de usar B simplemente creo >> el objeto de la clase B e inyecto una implementación para el método >> mi_servicio. >> >> Codigo de Ejemplo: >> ################################### >> class A: >> def mi_servicio(self): >> print("servicio que imprime un mensaje en pantalla") >> >> class B: >> def mi_servicio(self): >> """ >> Como implementacion de este metodo puede usarse A.mi_servicio o >> cualquier otro compatible. >> """ >> raise NotImplementedError() >> >> # luego cuando deseo usar B >> a = A() >> b = B() >> b.mi_servicio = a.mi_servicio >> ################################## >> La ultima parte de creación del objeto b e inyección de dependencias lo hago >> utilizando una >> librería de inyección de dependencias sencilla de solo dos funciones >> (inject() y create_descriptor()) >> >> En el ejemplo de arriba se asume que mi_servicio es opcional para B, en caso >> de ser requerido lo >> adiciono como un argumento de inicialización de la clase B y paso >> a.mi_servicio como argumento del >> constructor. >> >> Espero comprendas que inyección de dependencias no quiere decir emplear un >> contenedor, ni una librería, >> sino dejar bien claro quien requiere algo que lo ofrece otro. >> >> Atentamente >> -- >> Ing. Yeiniel Suárez Sosa >> Profesor Instructor, Dep. Automática >> FIE, UCLV >> >> >> On 2013-10-21 09:37, Ander Garmendia wrote: >>> >>> Buenas, >>> >>> estoy 'jugando' con decoradores y haciendo diferentes pruebas y tengo >>> una duda que quizá alguien me pueda aclarar. >>> >>> Digamos que tenemos una clase ( llamemosla B ) a la que queremos >>> añadir una funcionalidad (llamemosla F). El método clásico sería >>> heredar desde la clase base ( B ) y crear una nueva clase ( llamemosla >>> C ) que implementase nuestra funcionalidad ( F ). Hasta aquí todo >>> normal y corriente. >>> >>> Ahora llega python y nos ofrece los decoradores, por lo tanto, podemos >>> crear una clase decoradora ( llamemosla D ) que implemente la >>> funcionalidad ( F ) y que decorando una clase ( volvamos a la clase B >>> ), añade la funcionalidad F en la clase B sin necesidad de herencias >>> de ningún tipo. >>> >>> Visto así, todo parece muy cómodo, se escribe menos código, hay menos >>> clases implicadas, etc. >>> Y como todo parece muy bonito, aquí surge mi duda: ¿Está esta practica >>> extendida al escribir código en python ( es pythonico y aceptable ) ? >>> ¿ o es mas una prueba conceptual ? >>> >>> Gracias de antemano y un saludo. >>> >>> Ander. >>> _______________________________________________ >>> Python-es mailing list >>> Python-es@python.org >>> https://mail.python.org/mailman/listinfo/python-es >>> FAQ: http://python-es-faq.wikidot.com/ >> >> >> >> _______________________________________________ >> Python-es mailing list >> Python-es@python.org >> https://mail.python.org/mailman/listinfo/python-es >> FAQ: http://python-es-faq.wikidot.com/ > > > > -- > Juan B Cabral > _______________________________________________ > Python-es mailing list > Python-es@python.org > https://mail.python.org/mailman/listinfo/python-es > FAQ: http://python-es-faq.wikidot.com/ -- Sergio Fernández <ser...@wikier.org> _______________________________________________ Python-es mailing list Python-es@python.org https://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/