Python 状态机设计 [英] Python state-machine design

查看:89
本文介绍了Python 状态机设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于这个Stack 溢出问题(C状态机设计),Stack Overflow 的人能否与我(和社区)分享您的 Python 状态机设计技术?

Related to this Stack Overflow question (C state-machine design), could you Stack Overflow folks share your Python state-machine design techniques with me (and the community)?

目前,我打算使用基于以下内容的引擎:

At the moment, I am going for an engine based on the following:

class TrackInfoHandler(object):
    def __init__(self):
        self._state="begin"
        self._acc=""

    ## ================================== Event callbacks

    def startElement(self, name, attrs):
        self._dispatch(("startElement", name, attrs))

    def characters(self, ch):
        self._acc+=ch

    def endElement(self, name):
        self._dispatch(("endElement", self._acc))
        self._acc=""

    ## ===================================
    def _missingState(self, _event):
        raise HandlerException("missing state(%s)" % self._state)

    def _dispatch(self, event):
        methodName="st_"+self._state
        getattr(self, methodName, self._missingState)(event)

    ## =================================== State related callbacks

但我确信在利用 Python 的动态特性(例如动态调度)的同时,有很多方法可以做到这一点.

But I am sure there are tons of ways of going at it while leveraging Python's dynamic nature (e.g. dynamic dispatching).

我正在研究引擎"的设计技术,它根据机器的状态"接收事件"和调度".

I am after design techniques for the "engine" that receives the "events" and "dispatches" against those based on the "state" of the machine.

推荐答案

我不太明白这个问题.State 设计模式非常清晰.请参阅设计模式书籍.

I don't really get the question. The State Design pattern is pretty clear. See the Design Patterns book.

class SuperState( object ):
    def someStatefulMethod( self ):
        raise NotImplementedError()
    def transitionRule( self, input ):
        raise NotImplementedError()

class SomeState( SuperState ):
    def someStatefulMethod( self ):
        actually do something()
    def transitionRule( self, input ):
        return NextState()

这是非常常见的样板文件,用于 Java、C++、Python(我相信其他语言也有).

That's pretty common boilerplate, used in Java, C++, Python (and I'm sure other languages, also).

如果您的状态转换规则碰巧是微不足道的,有一些优化可以将转换规则本身推入超类.

If your state transition rules happen to be trivial, there are some optimizations to push the transition rule itself into the superclass.

请注意,我们需要有前向引用,因此我们按名称引用类,并使用 eval 将类名转换为实际类.另一种方法是将转换规则设为实例变量而不是类变量,然后在定义所有类后创建实例.

Note that we need to have forward references, so we refer to classes by name, and use eval to translate a class name to an actual class. The alternative is to make the transition rules instance variables instead of class variables and then create the instances after all the classes are defined.

class State( object ):
    def transitionRule( self, input ):
        return eval(self.map[input])()

class S1( State ): 
    map = { "input": "S2", "other": "S3" }
    pass # Overrides to state-specific methods

class S2( State ):
    map = { "foo": "S1", "bar": "S2" }

class S3( State ):
    map = { "quux": "S1" }

在某些情况下,您的事件不像测试对象是否相等那么简单,因此更通用的转换规则是使用适当的函数-对象对列表.

In some cases, your event isn't as simple as testing objects for equality, so a more general transition rule is to use a proper list of function-object pairs.

class State( object ):
    def transitionRule( self, input ):
        next_states = [ s for f,s in self.map if f(input)  ]
        assert len(next_states) >= 1, "faulty transition rule"
        return eval(next_states[0])()

class S1( State ):
    map = [ (lambda x: x == "input", "S2"), (lambda x: x == "other", "S3" ) ]

class S2( State ):
    map = [ (lambda x: "bar" <= x <= "foo", "S3"), (lambda x: True, "S1") ]

由于规则是按顺序评估的,因此允许使用默认"规则.

Since the rules are evaluated sequentially, this allows a "default" rule.

这篇关于Python 状态机设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆