2017-04-07 1 views
0

あなたの助けが必要です。https://github.com/tyarkoni/transitions/issues/198に示すタイムアウトメカニズムを実行できません。

ここに記載されている私のステートマシンのタイムアウト機能を実装しようとしています。transitions library。マシンの起動時には、受信待ち状態:

TypeError: init() got an unexpected keyword argument 'parent'

すべてのcunstructorパラメータが伝達されますが、

私のコード(Pythonの2.7.6/5.1.0 IPython):

from transitions.extensions import HierarchicalMachine as Machine 
import time 
from threading import Thread 
from transitions import State 


class Timeout(Thread): 

    def __init__(self, func, timeout): 
     super(Timeout, self).__init__() 
     self.func = func 
     self.timeout = timeout 
     self.canceled = False 
     print 'Starting countdown' 
     self.start() 

    def run(self): 
     time.sleep(self.timeout) 
     print 'Timeout occurred' 
     if not self.canceled: 
      self.func() 


class TimeoutState(State): 

    def __init__(self, name, timeout=None, *args, **kwargs): 
     self.timeout = timeout 
     super(TimeoutState, self).__init__(name=name, *args, **kwargs) 



class TimeoutMachine(Machine): 

    def __init__(self, model, states, transitions, initial, title): 

     super(Machine, self).__init__( model=model, 
             states=states, 
             transitions=transitions, 
             initial=initial, 
             name=title, 
             queued=True, 
             auto_transitions=True, 
             send_event=True) 


    def _create_state(self, *args, **kwargs): 
     return TimeoutState(*args, **kwargs) 



class Model(): 

    def __init__(self): 
     self.timer = None 

    def set_timeout(self, event_data): 
     timeout=event_data.kwargs.pop('timeout',3) 
     self.timer = Timeout(self.doTimeout, timeout) 


model = Model() 
transitions = [{'doTimeout', 'B', 'C'}] 
b = TimeoutState(name='B',timeout=5, on_enter='set_timeout') 
machine = TimeoutMachine(model=model, states=['A', b, 'C'], 
         transitions=transitions, initial='A', 
         title='TestMachineWithTimeouts') 

エラー・スタック:

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2881, in run_code 
    exec(code_obj, self.user_global_ns, self.user_ns) 
    File "<ipython-input-40-747d39e2dc66>", line 1, in <module> 
    t.TimeoutMachine(model=model, states=['A', b, 'C'], transitions=transitions, initial='A', title='TestMachineWithTimeouts') 
    File "/home/sge/workspace_neon/ocpp16j_dev/_test_.py", line 61, in __init__ 
    send_event=True) 
    File "build/bdist.linux-i686/egg/transitions/core.py", line 364, in __init__ 
    self.add_states(states) 
    File "build/bdist.linux-i686/egg/transitions/extensions/nesting.py", line 264, in add_states 
    new_states = self.traverse(states, *args, **kwargs) 
    File "build/bdist.linux-i686/egg/transitions/extensions/nesting.py", line 183, in traverse 
    ignore_invalid_triggers=ignore)) 
    File "/home/sge/workspace_neon/ocpp16j_dev/_test_.py", line 78, in _create_state 
    return TimeoutState(*args, **kwargs) 
    File "/home/sge/workspace_neon/ocpp16j_dev/_test_.py", line 46, in __init__ 
    super(TimeoutState, self).__init__(name=name, *args, **kwargs) 
TypeError: __init__() got an unexpected keyword argument 'parent' 

その上で何が悪いですか?どんな手掛かり?

ありがとうございました!

答えて

1

あなたの例で(少なくとも)3つの問題があります

  • が問題:HierarchicalMachineはソリューション

    • transitions.extensions.nesting.NestedState種類の状態が必要になります。ただ、正しい状態をサブクラス化。最も簡単な修正はfrom transitions.extensions.nesting import NestedState as State
  • 問題でfrom transitions import Stateを置き換えるために、次のようになります。TimeoutMachine.__init__であなたの代わりに、サブクラスの基底クラスでsuperを呼び出します。実際にはMachineの基本クラスの__init__メソッドがあればそれを呼び出します。

    • ソリューション:変更super(Machine, self).__init__問題
  • super(TimeoutMachine, self).__init__へ:移行は、セットとして定義されているがtransitionsは、この目的のために、配列や辞書をサポートしています。

    • ソリューション:あなたのTimeoutMachineをsublclassし、デフォルトの状態としてTimeoutStateを使用しているので、手動で状態を作成する必要はありません。どちらかtransitions=[['doTimeout', 'B', 'C']]またはtransitions=[{'trigger':'doTimeout', 'source':'B', 'dest':'C'}]

そして、もう一つの発言にtransitions = [{'doTimeout', 'B', 'C'}]を変更します。代わりに、このようなあなたの状態を定義することができます。コードの作業 states = ['A', 'C', {'name': 'B', 'timeout': 5, 'on_enter': 'set_timeout'}]

:バック休暇から

from transitions.extensions import HierarchicalMachine as Machine 
import time 
from threading import Thread 
from transitions.extensions.nesting import NestedState as State 


class Timeout(Thread): 

    def __init__(self, func, timeout): 
     super(Timeout, self).__init__() 
     self.func = func 
     self.timeout = timeout 
     self.canceled = False 
     print 'Starting countdown' 
     self.start() 

    def run(self): 
     time.sleep(self.timeout) 
     print 'Timeout occurred' 
     if not self.canceled: 
      self.func() 


class TimeoutState(State): 

    def __init__(self, name, timeout=None, *args, **kwargs): 
     self.timeout = timeout 
     super(TimeoutState, self).__init__(name=name, *args, **kwargs) 


class TimeoutMachine(Machine): 

    def __init__(self, model, states, transitions, initial, title): 
     super(TimeoutMachine, self).__init__(model=model, 
              states=states, 
              transitions=transitions, 
              initial=initial, 
              name=title, 
              queued=True, 
              auto_transitions=True, 
              send_event=True) 

    def _create_state(self, *args, **kwargs): 
     return TimeoutState(*args, **kwargs) 


class Model: 

    def __init__(self): 
     self.timer = None 

    def set_timeout(self, event_data): 
     timeout = event_data.kwargs.pop('timeout', 3) 
     self.timer = Timeout(self.doTimeout, timeout) 


model = Model() 
transitions = [{'trigger': 'doTimeout', 'source':'B', 'dest':'C'}] 
states = ['A', 'C', {'name': 'B', 'timeout': 5, 'on_enter': 'set_timeout'}] 
machine = TimeoutMachine(model=model, states=states, 
         transitions=transitions, initial='A', 
         title='TestMachineWithTimeouts') 
model.to_B() 
+0

は、この素敵なサプライズを得た;)そのためのおかげで! – steval

関連する問題