[Python] Python实现的一个简单的状态框架 →→→→→进入此内容的聊天室

来自 , 2020-09-17, 写在 Python, 查看 124 次.
URL http://www.code666.cn/view/045752bc
  1. from time import sleep
  2. from random import randint, shuffle
  3.  
  4. class StateMachine(object):
  5.     ''' Usage:  Create an instance of StateMachine, use set_starting_state(state) to give it an
  6.        initial state to work with, then call tick() on each second (or whatever your desired
  7.        time interval might be. '''
  8.  
  9.     def set_starting_state(self, state):
  10.         ''' The entry state for the state machine. '''
  11.         state.enter()
  12.         self.state = state
  13.        
  14.     def tick(self):
  15.         ''' Calls the current state's do_work() and checks for a transition '''
  16.         next_state = self.state.check_transitions()
  17.        
  18.         if next_state is None:
  19.             # Stick with this state
  20.             self.state.do_work()
  21.         else:
  22.             # Next state found, transition to it
  23.             self.state.exit()
  24.             next_state.enter()
  25.             self.state = next_state
  26.        
  27.    
  28. class BaseState(object):
  29.     ''' Usage: Subclass BaseState and override the enter(), do_work(), and exit() methods.
  30.        
  31.            enter()    -- Setup for your state should occur here.  This likely includes adding
  32.                          transitions or initializing member variables.
  33.                      
  34.            do_work()  -- Meat and potatoes of your state.  There may be some logic here that will
  35.                          cause a transition to trigger.
  36.                          
  37.            exit()     -- Any cleanup or final actions should occur here.  This is called just
  38.                          before transition to the next state.
  39.    '''
  40.    
  41.     def add_transition(self, condition, next_state):
  42.         ''' Adds a new transition to the state.  The "condition" param must contain a callable
  43.            object.  When the "condition" evaluates to True, the "next_state" param is set as
  44.            the active state. '''
  45.         # Enforce transition validity
  46.         assert(callable(condition))
  47.         assert(hasattr(next_state, "enter"))
  48.         assert(callable(next_state.enter))
  49.         assert(hasattr(next_state, "do_work"))
  50.         assert(callable(next_state.do_work))
  51.         assert(hasattr(next_state, "exit"))
  52.         assert(callable(next_state.exit))
  53.        
  54.         # Add transition
  55.         if not hasattr(self, "transitions"):
  56.             self.transitions = []
  57.         self.transitions.append((condition, next_state))
  58.  
  59.     def check_transitions(self):
  60.         ''' Returns the first State thats condition evaluates true (condition order is randomized) '''
  61.         if hasattr(self, "transitions"):
  62.             shuffle(self.transitions)
  63.             for transition in self.transitions:
  64.                 condition, state = transition
  65.                 if condition():
  66.                     return state
  67.  
  68.     def enter(self):
  69.         pass
  70.        
  71.     def do_work(self):
  72.         pass
  73.        
  74.     def exit(self):
  75.         pass
  76.  
  77.  
  78. ##################################################################################################
  79. ############################### EXAMPLE USAGE OF STATE MACHINE ###################################
  80. ##################################################################################################
  81. class WalkingState(BaseState):
  82.     def enter(self):
  83.         print("WalkingState: enter()")
  84.         def condition(): return randint(1, 5) == 5
  85.         self.add_transition(condition, JoggingState())
  86.         self.add_transition(condition, RunningState())
  87.        
  88.     def do_work(self):
  89.         print("Walking...")
  90.        
  91.     def exit(self):
  92.         print("WalkingState: exit()")
  93.        
  94.        
  95. class JoggingState(BaseState):
  96.     def enter(self):
  97.         print("JoggingState: enter()")
  98.         self.stamina = randint(5, 15)
  99.         def condition(): return self.stamina <= 0
  100.         self.add_transition(condition, WalkingState())
  101.        
  102.     def do_work(self):
  103.         self.stamina -= 1
  104.         print("Jogging ({0})...".format(self.stamina))
  105.        
  106.     def exit(self):
  107.         print("JoggingState: exit()")
  108.        
  109.        
  110. class RunningState(BaseState):
  111.     def enter(self):
  112.         print("RunningState: enter()")
  113.         self.stamina = randint(5, 15)
  114.         def walk_condition(): return self.stamina <= 0
  115.         self.add_transition(walk_condition, WalkingState())
  116.        
  117.         def trip_condition(): return randint(1, 10) == 10
  118.         self.add_transition(trip_condition, TrippingState())
  119.        
  120.     def do_work(self):
  121.         self.stamina -= 2
  122.         print("Running ({0})...".format(self.stamina))
  123.        
  124.     def exit(self):
  125.         print("RunningState: exit()")
  126.        
  127.        
  128. class TrippingState(BaseState):
  129.     def enter(self):
  130.         print("TrippingState: enter()")
  131.         self.tripped = False
  132.         def condition(): return self.tripped
  133.         self.add_transition(condition, WalkingState())
  134.        
  135.     def do_work(self):
  136.         print("Tripped!")
  137.         self.tripped = True
  138.        
  139.     def exit(self):
  140.         print("TrippingState: exit()")
  141.        
  142.  
  143. if __name__ == "__main__":
  144.     state = WalkingState()
  145.    
  146.     state_machine = StateMachine()
  147.     state_machine.set_starting_state(state)
  148.    
  149.     while True:
  150.         state_machine.tick()
  151.         sleep(1)
  152.  
  153. #//python/8661

回复 "Python实现的一个简单的状态框架"

这儿你可以回复上面这条便签

captcha