[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