¿Cómo puedo ajustar un modelo que no sea Traits para usar con Python Traits?

Me gustaría envolver una clase de modelo que no sea Traits para usar con Python Traits. Mi objective es escribir una interfaz de usuario basada en rasgos para manipular una clase de modelo “externa”. La clase de modelo externo ha sido generada por SWIG, por lo que no puedo agregar enthought.traits.api.HasTraits como un antepasado (creo que, aunque pueda estar equivocado).

Mi mejor bash actual es

from enthought.traits.api import HasStrictTraits, Property, Instance class ExternalModel(): foo = 'foo' class TraitsModel(HasStrictTraits): _e = Instance(ExternalModel) def __init__(self): self._e = ExternalModel() self.add_trait('foo', Property(lambda :getattr(self._e,'foo' ), lambda attr:setattr(self._e,'foo',attr))) 

lo que hace que la clase TraitsModel basada en Traits tenga una propiedad mutable que delega en la instancia de ExternalModel contenida que no es Traits. Sin embargo, TraitsModel.trait_names () no informa “foo” como un rasgo reconocido.

¿Alguna sugerencia sobre cómo hacer que TraitsModel informe un rasgo ‘foo’ que está vinculado a ExternalModel? enthought.traits.api.DelegatesTo parece requerir que el objective sea una clase de Rasgos (aunque puede que no haya encontrado la invocación correcta y eso es posible).

Un enfoque más de MVC-ish es probablemente tener una vista basada en Rasgos de mi Modelo Externo. No he podido encontrar un modelo que no sea de Rasgos para una vista basada en Traits. Sugerencias en esa dirección también son bienvenidas.

    Actualización He descubierto cómo obtener HasTraits como la superclase ExternalModel utilizando el enfoque en http://agentzlerich.blogspot.com/2011_05_01_archive.html y parece haber sido una completa pérdida de tiempo. Al parecer, el vudú SWIG y el hoodoo Traits no encajan. Ajustar ExternalModel dentro de TraitsModel ya que esta pregunta parece ser la mejor ruta.

     from enthought.traits.api import HasStrictTraits, Instance, Property class ExternalModel(object): foo = 'foo' class TraitsModel(HasStrictTraits): _e = Instance(ExternalModel, ExternalModel()) def __init__(self): ''' >>> wrapper = TraitsModel() >>> wrapper.foo 'foo' >>> wrapper._e.foo = 'bar' >>> wrapper.foo 'bar' >>> wrapper.trait_names() ['trait_added', '_e', 'foo', 'trait_modified'] ''' HasStrictTraits.__init__(self) for trait in (name for name in dir(self._e) if not name.startswith('__')): self.__class__.add_class_trait( trait, Property( lambda:getattr(self._e, trait), lambda attr:setattr(self._e, trait, attr) ) ) if __name__ == '__main__': import doctest doctest.testmod() 

    Una solución bastante robusta es usar add_class_trait de la clase HasTraits , junto con dir(self._e) para obtener los nombres de los atributos de clase de ExternalModel y una expresión de generador / comprensión de lista para filtrar los nombres de los métodos de la clase mágica ( filter con una la función apropiada funcionaría mejor para envolver una clase más compleja).

    También:

    • ExternalModel debe heredar de object

    • __init__ debe llamar a HasStrictTraits.__init__ (o super(HasStrictTraits, self).__init__() )

    • _e también se puede crear en la statement de rasgo de instancia como el segundo argumento usando ExternalModel() o incluso () , o como un método de TraitsModel como:

       def __e_default(self): # note preceding underscore return ExternalModel() 

    Por último, tengo una copia un poco antigua de las API de Enthought, incluidas las características, que pueden ser muy útiles.