2

Pythonトレイトで使用するために非トレイトモデルクラスをラップしたいと思います。私の目標は、「外部」モデルクラスを操作するためのTraitsベースのUIを作成することです。外部モデルクラスはSWIGによって生成されているため、祖先としてenthought.traits.api.HasTraitsを追加することはできません(間違っているかもしれませんが)。

私の現在の最善の試みは

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は、含まれている非TraitsExternalModelインスタンスに委任する可変プロパティを持ちます。ただし、TraitsModel.trait_names()は、認識された特性として「foo」を報告しません。

TraitsModelにExternalModelにリンクされている「foo」トレイトを報告させる方法についての提案はありますか?enthought.traits.api.DelegatesToは、ターゲットがTraitsクラスである必要があるようです(ただし、正しい呼び出しが見つからなかった可能性があり、それは可能です)。

よりMVC風のアプローチは、おそらく、ExternalModelのトレイトベースのビューを持つことです。トレイトベースのビューに非トレイトモデルがあることを理解できませんでした。その方向への提案も大歓迎です。

更新http://agentzlerich.blogspot.com/2011_05_01_archive.htmlのアプローチを使用して、HasTraitsをExternalModelスーパークラスとして取得する方法を理解しましたが、これは完全に時間の無駄だったようです。どうやらSWIGブードゥーとトレイツフードゥーはジャイブしません。この質問が尋ねるように、TraitsModel内でExternalModelをラップするのが最善の方法のようです。

4

1 に答える 1

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

かなり堅牢な解決策は、クラス属性の名前を取得するためにadd_class_traitクラスのHasTraitsを使用し、ジェネレータ式/リスト内包表記を使用して魔法のクラス メソッド名をフィルタリングすることです (適切な関数を使用すると、より複雑なクラス)。dir(self._e)ExternalModelfilter

また:

  • ExternalModelから継承する必要がありますobject

  • __init__HasStrictTraits.__init__(またはsuper(HasStrictTraits, self).__init__())を呼び出す必要があります

  • _eExternalModel()またはを使用して 2 番目の引数として()、または次のような TraitsModel のメソッドとして Instance trait 宣言で作成することもできます。

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

最後に、非常に便利なTraits を含む Enthought API の少し古いコピーがあります。

于 2011-06-18T12:47:28.730 に答える