[Python-es] Traits en Python

Chema Cortes pych3m4 en gmail.com
Jue Ago 29 12:29:01 CEST 2013


El día 29 de agosto de 2013 08:24, Olemis Lang <olemis en gmail.com> escribió:
> On 8/28/13, Chema Cortes <pych3m4 en gmail.com> wrote:
>> El día 28 de agosto de 2013 01:44, Olemis Lang <olemis en gmail.com> escribió:
>>> Busco una librería q implemente un mecanismo de extensión similar a
>>> los traits (self, scala, smalltalk, ...) . Lo q necesito es extender
>>> el comportamiento de clases sin herencia múltiple i.e. mixins . Si el
>>> mecanismo funciona a nivel d objetos en vez d clases puede q m sirva
>>> también .
>>>
>>> En mi corta investigación he encontrado :
>>>
>>>   - https://pypi.python.org/pypi/strait : en la línea d lo q necesito
>>> hacer
>>>     pero no permite redefinición (overrides) ni encadenamiento.
>>>   - http://pypi.python.org/pypi/Traits :
>>>   - https://pypi.python.org/pypi/simpletraits : lejanamente
>>>     parecido a lo q quiero hacer , creo q ni siquiera tiene q ver ...
>>>
>>> ¿Alguien conoce otra librería o alguna otra variante q pueda recomendar?
>>
>> Viendo estas referencias, hay quién confunde "traits" con la
>> programación por contrato. Un trait define un comportamiento
>> determinado mediante:
>>
>> - Métodos "concretos" que implementan un comportamiento determinado
>> - Métodos "abstractos" que parametrizan un comportamiento determinado
>>
>
> el vocabulario técnico parece ser más rico de lo q yo esperaba ... hay
> un montón d cosas a las q le dicen traits sin relación alguna entre
> ellas ; pero bueno, estaba hablando d algo como los traits d Scala ...
>
> [...]
>>
>> Supongo que ésto ya lo habías probado.
>
> ;)
>
>> Según pidés, no quieres
>> "mixins", que equivaldría a que no quede rastro en el __mro__ .
>
> No es solamente por el hecho del mro , la cuestión consiste en q en el
> modelo q necesitaría :
>
>   1. habría **muchas** clases parciales
>   2. q extenderían / modificarían el comportamiento d una clase base
>   3. pero la composición q se necesita en un caso determinado se
>       determina en tiempo d ejecución (o sea, se generan clases)
>   4. y el número d clases en cada composición puede ser grande
>
> razón por la cual estaba creyendo conveniente tener el equivalente d (Scala)
>
> new Class() with Trait1 with Trait2 with ... Trait_n{
>   def transform(obj: String): obj.toLower()
> }
>
> con una sintaxis más o menos así
>
> cls = Trait1(Trait2(... Trait_n(Class)))
> obj = cls()

No entiendo bien. La versión "decorador" que te había puesto puede
hacer este "encadenado":

cls = Trait1.register(Trait2.register(....Trait_n.register(Class)))

Si lo quieres más práctico, cambia el método register por un método __call__

Otra cosa distinta es que quieras crear clases anónimas como en scala.
Pero, según Guido, éso es sólo para listos. :-P

>
>> Se me
>> ocurre complicar algo más Trait para que sea capaz de "inyectar"
>> métodos:
>>
>> class Trait(ABCMeta):
>>
>>     def __init__(self, name, bases, dic):
>>         self.__dic=dic
>>
>>     def register(self, cls):
>>         super().register(cls)
>>         for k,v in self.__dic.items():
>>             if not hasattr(cls,k):
>>                 setattr(cls,k,v)
>>         return cls
>>
>> El modo de empleo de MyTrait sería como decorador:
>>
>> @MyTrait.register
>> class MyClass(object):
>>     def __str__(self):
>>         return "MyTrait"
>>
>> assert(issubclass(MyClass, MyTrait))
>> assert(MyTrait not in MyClass.__mro__)
>>
>> c=MyClass()  ##OK
>> c.print()  ## >>>MyTrait<<<
>>
>> El problema de este último sistema es que no tiene en cuenta los
>> métodos abstractos ya que no está soportado añadir métodos abstractos
>> dinámicamente. Como solución, se podría suplantar los métodos
>> abstractos por una implementación que lanze una excepción
>> "NotImplementedError" o similar.
>>
>
> Algo parecido a esto es lo q busco pero con resolución dinámica d
> nombres (i.e. sin copia) . D todas formas estaba tratando d evitar
> tener q hacerlo. Pensé q era algo tan común q ya debería haber algo al
> respecto , pero creo q no m va a quedar otro remedio q empezarlo desde
> cero .
> :'(
>
> [...]
>
> --
> Regards,
>
> Olemis - @olemislc
>
> Apache™ Bloodhound contributor
> http://issues.apache.org/bloodhound
> http://blood-hound.net
>
> Blog ES: http://simelo-es.blogspot.com/
> Blog EN: http://simelo-en.blogspot.com/
>
> Featured article:
> Apache™ Bloodhound 0.7 listo para descarga -
> http://goo.gl/fb/OwzmM
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/



-- 
Hyperreals *R  "Quarks, bits y otras criaturas infinitesimales":
http://ch3m4.org/blog
Buscador Python Hispano: http://ch3m4.org/python-es


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