2015-04-12 50 views
0

所以我想寫一個狀態機類,就像下面編寫獨特的功能使用相同的參數

from states import StateMachineExample 

sm = StateMachineExample() 

while True: 
    a = input_source1() 
    b = input_source2() 
    c = input_source2() 

    sm.tick(a,b,c) 

的StateMachine要跟蹤的狀態,並且所有用戶所要做的就是給它餵食每個循環的新輸入使用tick()。類定義是類似以下內容:

class StateMachineBase(object): 
    __metaclass__ = ABCMeta 

    def __init__(self,init_state): 
     self._state = init_state 

    def tick(self,*args): 
     """ 
     Let the state machine process the next set of inputs. 
     """ 
     # The next state is defined by what the current state's 
     # function returns 
     newstate = self._state(*args) or self._state 
     self._state = newstate 

class StateMachineExample(StateMachineBase): 

    def __init__(self): 
     super(StateMachineExample,self).__init__(self,self.StateA) 

    def StateA(a,b,c): 
     if condition_on(a,b,c): 
      return self.StateB # Transition to StateB 
     else: 
      return self.StateA 

    def StateB(a,b,c): 
     if other_condition_on(a,b,c): 
      return self.StateA 
     else: 
      return self.StateB 

問題

反正是有避免必須明確說明a,b,c參數爲每個功能(狀態)定義在StateMachineExample類?即是否有可能在一個地方定義參數並定義了一整套函數的參數?我意識到這整個實現可能是有缺陷的,所以我肯定會接受不同的方法。

注意

這是可能做到這一點與*args但隨後的參數具有相對於Args tuple中被引用。我希望能夠在功能中按名稱引用參數,即a,b,c

我發現的最接近的解決方案是將輸入定義爲類成員變量,每次調用tick()時都可以更新它們。我希望有比這更優雅的東西。

+0

爲什麼要通過代碼而不是數據定義狀態機? –

+0

@ IgnacioVazquez-Abrams你能詳細說明一下嗎?該類的重點是允許抽象在解釋時定義的狀態機的細節。如果有幫助,本例中的狀態機可以識別並細分視頻源中的一隻手。因此(粗略地說)每個週期的輸入是來自照相機饋送的圖像。然後用戶可以檢查類實例以查看狀態機當前是否正在跟蹤手並檢索諸如手的邊界框之類的相關屬性。 – toes

回答

0

正如Ignacio所說,狀態機通常依賴於一個變量,它指向下一個要執行的狀態。這種「下一個」狀態通常被頻繁地調用,並且僅在必要時才被改變(如果存在導致狀態改變的事件)。從那裏開始,新的狀態就是被調用的狀態,直到下一個事件出現。所以,如果你有一系列的事件,並且切換是常見的(頻繁 - 幾乎在每個週期),那麼狀態機就沒有太大的意義。您只需實施一系列if語句。

通常,在狀態機中,您將有一個變量,其中包含對要調用的下一個函數的引用。發生事件時,此變量將更改爲下一個狀態。

假設你有一個變量'routine_to_go_to_work'。通常這個變量包含對'Walk_to_work'的引用。但是,如果你打破了一條腿,你可以改變這個變量來指向'Call_a_taxi'......直到你恢復並重新設置變量爲'Walk_to_work'。但你總是打電話給'routine_to_go_to_work',無論它指向哪個實際功能。

+0

我想我明白你的意思了。我認爲目前還不清楚的是,在我的例子中,我已經把時鐘滴答作爲'事件'(因此是'tick()'函數)。在較低的級別上,機器在每次迭代中處理輸入,然後使用它來確定是否發生了更高級別的事件(例如,在視頻中檢測到手)。我認爲你所建議的是我爲狀態機之外的這些事件定義了條件,並且只在事件發生時調用機器。是對的嗎? – toes

+1

你有這些例子嗎? (http://www.ibm.com/developerworks/library/l-python-state/似乎有格式化的一些問題)。它們非常有趣......它與我想要建議的非常相似(即從一個指針調用函數,在本例中所有函數都在一個表中) – jcoppens

+0

感謝您的參考!簡而言之,這裏提出的想法是,StateMachine從用戶那裏接受一些初始輸入,然後狀態函數從內部處理從一個狀態到另一個狀態的數據傳遞。如示例所示,傳遞的數據可能會包含一種文件處理程序,狀態機可以從中請求新輸入。這看起來像我正在尋找的解決方案。謝謝! – toes

相關問題