无法运行https://github.com/tyarkoni/transitions/issues/198中显示的超时机制。

时间:2017-04-07 09:54:37

标签: python-2.7 ipython transitions

需要你的帮助。

尝试为此处提到的状态机transitions library设置超时功能。在初始化机器时继续接收:

  

TypeError: init ()得到了一个意外的关键字参数' parent'

尽管传播了所有的构造函数参数。

我的代码(Python 2.7.6 / IPython 5.1.0):

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 个答案:

答案 0 :(得分:1)

您的示例存在(至少)三个问题:

  • 问题:HierarchicalMachine要求状态为transitions.extensions.nesting.NestedState

    • 解决方案:只是继承正确的状态。最简单的解决方法是将from transitions import State替换为from transitions.extensions.nesting import NestedState as State
  • 问题:在TimeoutMachine.__init__中,您使用基类而不是子类调用super。如果有的话,这实际上会调用__init__基类的Machine方法。

    • 解决方案:将super(Machine, self).__init__更改为super(TimeoutMachine, self).__init__
  • 问题:转换定义为集合,但transitions仅支持数组或字典。

    • 解决方案:将transitions = [{'doTimeout', 'B', 'C'}]更改为transitions=[['doTimeout', 'B', 'C']]transitions=[{'trigger':'doTimeout', 'source':'B', 'dest':'C'}]

还有一句话:由于您将TimeoutMachine子类化并使用TimeoutState作为默认状态,因此您不必手动创建状态。你可以这样定义你的状态: 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()
相关问题