python状态机实现

序言:
状态机模式是一种编程中非常好用的过程控制模型。

基类
import abc


class StateMachine(metaclass=abc.ABCMeta):
    STATE_START = 1

    STATE_WAIT = 98
    STATE_ERROR = 99
    STATE_FINISH = 100

    STATE_END = 1000

    def __init__(self):
        self.startState = 0
        self.endStates = set()
        self.handlers = {}
        self._init_state()

    def _init_state(self):
        self.add_state(self.STATE_START, self.start, False)
        self.add_state(self.STATE_END, self.end, True)

    def add_state(self, state, handler, end=False):
        self.handlers[state] = handler
        if end:
            self.endStates.add(state)

    def add_states(self, handlers):
        for each in handlers:

            self.add_state(*each)

    def run(self, cargo, state=0):
        self.__set_start(state)

        return self.__run(cargo)

    def __set_start(self, state):
        if state >= self.STATE_START:
            self.startState = state
        else:
            self.startState = self.STATE_START

    def __run(self, cargo):

        def __handler_transfer(_handler):
            _state = _handler(cargo)
            if _state in self.endStates:
                return _state
            return __handler_transfer(self.handlers[_state])

        try:
            handler = self.handlers[self.startState]
        except KeyError:
            raise UnboundLocalError(f"state {self.startState} no have handler")
        if not self.endStates:
            raise UnboundLocalError("Need at least one endState")

        __handler_transfer(handler)

    @abc.abstractmethod
    def start(self, cargo):
        """必须要起始函数"""
        return self.STATE_END

    def end(self, cargo):
        """必须要结束函数"""
        return self.STATE_END
实现

我们模拟一个人的一天来深刻理解状态机

  • 1.首先定义Person对象
    class Person:
        def __init__(self, name="靓仔", state=0):
            self.name = name
            self.state = state
    
  • 2.定义一个打印状态的装饰器
    def process_print(func):
        def inner(*args):
            task = args[1]
            print(f"{task.name} handler执行前状态: {task.state}")
            res = func(*args)
            print(f"{task.name} handler执行后状态: {task.state}")
            return res
    
        return inner
    
  • 3.实现状态机
    import time
    
    class PersonStateMachine(StateMachine):
        GET_UP = 2
        WASH = 3
        EAT = 5
        WORK = 6
        SLEEP = 7
        HOME = 8
    
        def __init__(self):
            super().__init__()
            self.add_states(
                [
                    (self.GET_UP, self.get_up, 0),
                    (self.WASH, self.wash, 0),
                    (self.EAT, self.eat, 0),
                    (self.WORK, self.work, 0),
                    (self.SLEEP, self.sleep, 0),
                    (self.HOME, self.home, 0),
                ]
            )
    
        @process_print
        def start(self, cargo):
            cargo.state = self.GET_UP
            print("start ing")
            return cargo.state
    
        def get_up(self, cargo):
            cargo.state = self.WASH
            print("起床 ing")
            time.sleep(5)
            return cargo.state
    
        @process_print
        def wash(self, cargo):
            cargo.state = self.EAT
            print("洗漱 ing")
            time.sleep(5)
            return cargo.state
    
        @process_print
        def eat(self, cargo):
            cargo.state = self.WORK
            print("吃饭 ing")
            time.sleep(5)
            return cargo.state
    
        @process_print
        def work(self, cargo):
            cargo.state = self.SLEEP
            print("工作 ing")
            time.sleep(5)
            return cargo.state
    
        @process_print
        def sleep(self, cargo):
            cargo.state = self.HOME
            print("睡觉 ing")
            time.sleep(5)
            return cargo.state
    
        @process_print
        def home(self, cargo):
            cargo.state = self.STATE_END
            print("回家 ing")
            time.sleep(5)
            return cargo.state
    
    
    • 4.执行
      if __name__ == "__main__":
      	p_state = PersonStateMachine()
      	p = Person()
      	p_state.run(p)
      
  • 5.打印
    DEMO handler执行前状态: 0
    start ing
    DEMO handler执行后状态: 2
    起床 ing
    DEMO handler执行前状态: 3
    洗漱 ing
    DEMO handler执行后状态: 5
    DEMO handler执行前状态: 5
    吃饭 ing
    DEMO handler执行后状态: 6
    DEMO handler执行前状态: 6
    工作 ing
    DEMO handler执行后状态: 7
    DEMO handler执行前状态: 7
    睡觉 ing
    DEMO handler执行后状态: 8
    DEMO handler执行前状态: 8
    回家 ing
    DEMO handler执行后状态: 1000
    
    
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值