2017-09-25 11 views
1

Labview VIのように、必要なときにのみすべての出力が計算される入出力(一部の出力は入力の一部などに依存する場合があります)を含むオブジェクトが必要です。出力間にカスケード関係が存在する可能性があります。 output_1の計算結果はoutput_0の計算結果に依存します。Labviewのような振る舞い

のは、この単純化しすぎ例(私はoutput_0とoutput_1は、単一の手順で計算することができることを意識していますが、私はもちろん、より複雑なアプリケーションに目指すところ)考えてみましょう:

from traits.api import HasTraits, Int, Property, cached_property 

class A(HasTraits): 
    input_0 = Int 
    output_0 = Property(depends_on='input_0') 
    output_1 = Property(depends_on='output_0') 

    @cached_property 
    def _get_output_0(self): 
     print('_get_output_0') 
     return self.input_0**2 

    @cached_property 
    def _get_output_1(self): 
     print('_get_output_1') 
     return self.output_0**2 

a = A(input_0=3) 

問題ここでは、ということですoutput_1output_0に依存することが宣言されているように、output_0の値が(理解)input_0変更、すなわち毎回計算しなければならない上記のコードを実行すると '_get_output_0'が出力されます。

のように、イベントを使用して、より一貫性のある動作を持つことが可能です:

from traits.api import HasTraits, Int, Property, cached_property, Event 
from traitsui.api import View 

class A(HasTraits): 
    input_0 = Int 
    output_0 = Property(depends_on='input_0') 
    output_1 = Property(depends_on='output_0_changed') # <--- depends on Event now --- 
    output_0_changed = Event 

    @cached_property 
    def _get_output_0(self): 
     print('_get_output_0') 
     self.output_0_changed = True # <----- Event fired ---------- 
     return self.input_0**2 

    @cached_property 
    def _get_output_1(self): 
     print('_get_output_1') 
     return self.output_0**2 

    traits_view = View('input_0', 'output_0', 'output_1') 

a = A(input_0=3) 

万歳! の出力_0の計算はもう解雇されません。 output_0またはoutput_1については、関連する計算のみが開始されます。これまでのところ、とても良い...

残念ながら、

a.configure_traits() 

を発行すると、ダイアログボックスに input_0 の値を変更すると、output_0output_1の代替計算の無限ループになります。 traits.api docの状態についてon_trait_changeその現在のスレッドがUIスレッドの場合、通知はただちに実行されます。ここでは、これまでのところoutput_1output_0

間、したがって再帰呼び出し、私たちは、プロパティのを扱っているが、それは似たようなことがなければならない、通知をoutput_0_changed IOW実行され前に新しい値が設定されています私はこの再帰を取り除くための解決策を見出しませんでした。何か案が?

答えて

0

部分的な解決策は、_output_0形質を追加し、output_1_output_0に依存することです:

from traits.api import HasTraits, Int, Property, cached_property 
from traitsui.api import View 

class A(HasTraits): 
    _output_0 = Int 
    input_0 = Int 
    output_0 = Property(depends_on='input_0') 
    output_1 = Property(depends_on='_output_0') 

    @cached_property 
    def _get_output_0(self): 
     print('_get_output_0') 
     self._output_0 = self.input_0**2 
     return self._output_0 

    @cached_property 
    def _get_output_1(self): 
     print('_get_output_1') 
     return self.output_0**2 

    traits_view = View('input_0', 'output_0', 'output_1') 

a = A(input_0=3) 

ただし、設定ダイアログが開いている場合は、入力の変更はされて_get_output_0を作ります2回呼び出される前に一度_get_output_1そして一度...

関連する問題