[Python-es] Traits en Python

Olemis Lang olemis en gmail.com
Jue Ago 29 08:24:28 CEST 2013


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()

> 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


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