2017-09-25 100 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_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) 

萬歲! output_0的計算不再被解僱。詢問output_0output_1將以任何順序將只有啓動相關的計算。到目前爲止,一切都很好...

不幸的是,發行

a.configure_traits() 

和改變對話框input_0值將進入的OUTPUT_0OUTPUT_1替代計算的無限遞歸。 traits.api doc指出on_trait_change如果當前線程是UI線程,則通知立即執行。在這裏,我們正在處理房產的,但它應該是類似的東西,督察的output_0_changed通知執行之前設置新的值,因此到目前爲止之間OUTPUT_1 OUTPUT_0

遞歸調用,我沒有找到任何解決方案來擺脫這種遞歸。任何想法?

回答

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一直叫做兩次,一次在之前_get_output_1和之後一次...