6

私はPyCon 2010 のプレゼンテーションに取り組んでいます。約 2:30:45 で、プレゼンターはtrait event notificationsの説明を開始します。これにより、(とりわけ) aが変更されたときはいつでもサブルーチンを自動的に呼び出すことができます。traits trait

彼が与えた例の変更されたコピーを実行しています...この試行では、volumeまたはに変更を加えるたびに静的イベントを起動できるかどうかを確認しようとしていますinputs

from traits.api import HasTraits, Range, List, Float
import traits
class Amplifier(HasTraits):
    """
    Define an Amplifier (a la Spinal Tap) with Enthought's traits.  Use traits  
    to enforce values boundaries on the Amplifier's objects.  Use events to 
    notify via the console when the volume trait is changed and when new volume 
    traits are added to inputs.
    """
    volume = Range(value=5.0, trait=Float, low=0.0, high=11.0)
    inputs = List(volume)    # I want to fire a static trait event notification
                             # when another volume element is added

    def __init__(self, volume=5.0):
        super(Amplifier, self).__init__()
        self.volume = volume
        self.inputs.append(volume)

    def _volume_changed(self, old, new):
        # static event listener for self.volume
        if not (new in self.inputs):
            self.inputs.append(self.volume)
        if new == 11.0:
            print "This one goes to eleven... so far, we have seen", self.inputs

    def _inputs_changed(self, old, new):
        # static event listener for self.inputs
        print "Check it out!!"

if __name__=='__main__':
    spinal_tap = Amplifier()
    spinal_tap.volume = 11.0
    print "DIRECTLY adding a new volume input..."
    spinal_tap.inputs.append(4.0)
    try:
        print "NEGATIVE Test... adding 12.0"
        spinal_tap.inputs.append(12.0)
    except  traits.trait_errors.TraitError:
        print "Test passed"

このスクリプトを実行すると、コンソール出力で確認できるので、 に割り当てるとが起動されるThis one goes to eleven... so far, we have seen [5.0, 11.0]ことがわかります。_volume_changed()11.0spinal_tap.volume

ただし、 からのイベントはまったく表示されません_inputs_changed()。どんな例を作ってもList、イベントを発生させることができません。

_inputs_changed()これは私が見ている出力です...これまでに発火したという証拠はないことに注意してください。

[mpenning@Bucksnort ~]$ python spinaltap.py
This one goes to eleven... so far, we have seen [5.0, 11.0]
DIRECTLY adding a new volume input...
NEGATIVE Test... adding 12.0
Test passed
[mpenning@Bucksnort ~]$

これを Python2.6 / Cygwin / Windows 7 と Python 2.5 / Linux の両方で実行しました (すべて、Enthought のサイトから直接入手しtraitsたバージョン 4.0.0 を使用しています)。これまでに何を試しても結果は同じです。easy_install

List特性を使用するときに静的イベントを発生できるようにする必要がありますか? もしそうなら、私は何か間違ったことをしていますか?

4

2 に答える 2

5

彼らの単体テストを閲覧した後、Dictenthought のイベントユニットテスト カバレッジでトレイトのテストを見つけました。DictList

## Broken method definition: def _inputs_changed(self, old, new):
# container event static listeners must be in the form of _foo_items_changed()
def _inputs_items_changed(self, old, new):
    # static event listener for self.inputs
    if len(new.added) > 0:
        print "Check it out, we added %s to self.items" % new.added
    elif len(new.removed) > 0:
        print "Check it out, we removed %s from self.items" % new.removed

on_trait_change同様に、デコレータ (動的イベント通知に使用) をor ...traitsで呼び出す場合、同様の命名法が必要であることも発見したので、上記のコードを次のように書くこともできます。traits.api.Listtraits.api.Dict

from traits.api import on_trait_change
# ...
@on_trait_change('inputs_items')
def something_changed(self, name, new):
    # static event listener for self.inputs
    if len(new.added) > 0:
        print "Check it out, we added %s to self.items" % new.added
    elif len(new.removed) > 0:
        print "Check it out, we removed %s from self.items" % new.removed

いずれにせよ、コードを実行すると、期待どおりの出力が得られます。

[mpenning@Bucksnort ~]$ python spinaltap.py
Check it out, we added [5.0] to self.items
Check it out, we added [11.0] to self.items
This one goes to eleven... so far, we have seen [5.0, 11.0]
DIRECTLY adding a new volume input...
Check it out, we added [4.0] to self.items
NEGATIVE Test... adding 12.0
Test passed
[mpenning@Bucksnort ~]$
于 2011-12-04T07:54:21.813 に答える