序言:
状态机模式是一种编程中非常好用的过程控制模型。
基类
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)
- 4.执行
- 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