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_1がoutput_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_0とoutput_1の代替計算の無限ループになります。 traits.api docの状態についてon_trait_changeその現在のスレッドがUIスレッドの場合、通知はただちに実行されます。ここでは、これまでのところoutput_1とoutput_0
間、したがって再帰呼び出し、私たちは、プロパティのを扱っているが、それは似たようなことがなければならない、は通知をoutput_0_changed IOW実行され前に新しい値が設定されています私はこの再帰を取り除くための解決策を見出しませんでした。何か案が?