如何包装非Trait模型以与Python Traits一起使用? [英] How can I wrap a non-Traits model for use with Python Traits?

查看:115
本文介绍了如何包装非Trait模型以与Python Traits一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想包装一个非Trait模型类,以用于Python Traits.我的目标是编写一个基于Traits的UI来操纵外部"模型类.外部模型类由SWIG生成,因此我无法添加enthought.traits.api.HasTraits作为祖先(我认为,尽管我可能错了).

I would like to wrap a non-Traits model class for use with Python Traits. My goal is to write a Traits-based UI to manipulate an "external" model class. The external model class has been generated by SWIG and so I cannot add enthought.traits.api.HasTraits as an ancestor (I think, though I may be wrong).

我目前的最佳尝试是

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

导致基于Traits的类TraitsModel具有可变属性,该属性将委派给所包含的非Trait ExternalModel实例.但是,TraitsModel.trait_names()不会将'foo'报告为可识别的特征.

which causes the Traits-based class TraitsModel to have a mutable property which delegates to the contained non-Traits ExternalModel instance. However, TraitsModel.trait_names() doesn't report 'foo' as a recognized trait.

关于如何使TraitsModel报告与外部模型链接的'foo'特征的任何建议? enthought.traits.api.DelegatesTo似乎要求目标是Traits类(尽管我可能没有找到正确的调用,并且这是可能的).

Any suggestions for how to have TraitsModel report a 'foo' trait which is linked to ExternalModel? enthought.traits.api.DelegatesTo seems to require the target be a Traits class (though I may not have found the right invocation and that is possible).

更类似于MVC的方法可能是对我的ExternalModel进行基于特征的视图.我一直无法弄清楚基于Traits的视图具有非Trait模型.对此方向的建议也非常受欢迎.

A more MVC-ish approach is probably to have a Traits-based view of my ExternalModel. I've been unable to figure out having a non-Traits model for a Traits-based view. Suggestions in that direction also greatly welcome.

更新我已经通过

Update I have figured out how to get HasTraits as the ExternalModel superclass using the approach at http://agentzlerich.blogspot.com/2011_05_01_archive.html and it seems to have been a complete waste of time. Apparently the SWIG voodoo and the Traits hoodoo do not jive. Wrapping ExternalModel within TraitsModel as this question asks seems the best route.

推荐答案

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

一个相当健壮的解决方案是使用

A fairly robust solution is to use the add_class_trait of the HasTraits class, coupled with dir(self._e) to get the names of the class attributes of ExternalModel and a generator expression/list comprehension to filter the magic class method names (filter with an appropriate function would work better for wrapping a more complex class).

也:

  • ExternalModel应该从object

__init__应该调用HasStrictTraits.__init__(或super(HasStrictTraits, self).__init__())

_e,或者将其作为TraitsModel的方法,例如:

_e can also be created in the Instance trait declaration as the second argument using ExternalModel() or even (), or as a method of TraitsModel like:

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

最后,我有一个稍旧的Enthought API副本,包括特质,这可能非常方便.

Lastly, I have an slightly old copy of the Enthought APIs including Traits which can be very handy.

这篇关于如何包装非Trait模型以与Python Traits一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆