需求: 根据检测用户按下的热键切换脚本状态
需求分析如下:
例如写了一个一直点击右键的连点脚本.用户按下'Alt+P'则暂停脚本(暂停状态),
用户按下'Alt+R'则恢复运行(运行状态),
用户按下'Alt+N'就切换为'normal'正常运行状态(正常点击速度),
用户按下'Alt+L'则切换为'slow'低速运行状态(慢慢点击),
用户按下'Alt+H'则切换为'high'高速运行状态(疯狂点击),
例如用户按下"Alt+S/E"则退出程序(退出状态)
Python状态模式
状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
CPU占用率--最简单的状态模式案例:
码农不同时间工作状态:大话设计模式Python实现-状态模式 - Andy冉明 - 博客园www.cnblogs.com
其它:python-状态模式 - 蔚蓝的蓝 - 博客园www.cnblogs.com
另一个比较好用的设计模式--命令模式:python设计模式之命令模式_若云流风的专栏-CSDN博客blog.csdn.netpython命令模式_慕课手记www.imooc.com
# 对慕课手记的例子进行完善, 用队列记录命令,
# 能够一直ctrl+z撤销, 并增加了反撤销功能shift+ctrl+z.
# 实物----灯
class Light(object):
#可以初始化灯的类型,例如是厨房的灯还是起居室的灯
def __init__(self, light_type):
self.light_type = light_type
# self.states = ['Off', 'On']
self.state = 'Off'
#灯本身的控制方法,on和off,这里的on和off不同于遥控器的,这只是灯自己的方法,就像是洗衣机的甩干和漂洗一样
def on(self):
self.state = 'on'
self.info()
def off(self):
self.state = 'off'
self.info()
def info(self):
print(str(self.light_type) + " --- light " + self.state)
# 基类----命令
class Command:
def __init__(self, light):
self.light = light
# 执行
def execute(self):
pass
# 撤销
def undo(self):
pass
# ps: 反撤销就是执行上一个撤销的命令
# 开灯命令
class LightOnCommand(Command):
#传入某个电灯对象
def __init__(self, light):
# self.light = light
super().__init__(light)
#定义一个execute方法,调用传入对象的特定方法
def execute(self):
self.light.on()
def undo(self):
self.light.off()
# 关灯命令
class LightOffCommand(Command):
def __init__(self, light):
# self.light = light
super().__init__(light)
def execute(self):
self.light.off()
def undo(self):
self.light.on()
class RemoteController(object):
def __init__(self):
self.onCommand = {}
self.offCommand = {}
# 命令和撤销命令保存至[列表]中, 用来撤销操作[ctrl+z]和反撤销操作[shift+ctrl+z].
self.commands = []
self.undo_commands = []
# 这里是对遥控器的插槽和按钮进行定义
def setCommand(self, slot, onCommand, offCommand):
self.onCommand.setdefault(slot, onCommand)
self.offCommand.setdefault(slot, offCommand)
# 遥控器ON按钮按下后执行的动作
def onButtonWasPress(self, slot):
command = self.onCommand[slot]
command.execute()
self.commands.append(command)
self.undo_commands = [] # 若新增命令, 则清空撤销过的命令, 反撤销操作将不可使用.
# 遥控器OFF按钮按下后执行的动作
def offButtonWasPress(self, slot):
# self.offCommand[slot].execute()
command = self.offCommand[slot]
command.execute()
self.commands.append(command)
self.undo_commands = []
# 撤销 Ctrl+Z
def undoButtonWasPress(self):
if (self.commands == []):
print('Warnning: undoCommand error! self.commands is None!')
return
undoCommand = self.commands.pop()
undoCommand.undo()
self.undo_commands.append(undoCommand) # 执行过的[撤销操作]保存至undo_commands, 用来[反撤销操作].
# 反撤销(双重撤销, Shift+Ctrl+Z)
def undo_undoButtonWasPress(self):
if(self.undo_commands == []):
print('Warnning: undo_undo_commands error! self.undo_commands is None!')
return
undo_undo_command = self.undo_commands.pop()
print(id(undo_undo_command), '--',undo_undo_command.__class__.__name__)
undo_undo_command.execute()
self.commands.append(undo_undo_command) # 将反撤销操作重新加入执行命令队列
def commands_info(self):
# info = [id(command) for command in self.commands]
info = [command.__class__.__name__ for command in self.commands]
print(info)
def undo_commands_info(self):
# info = [id(command) for command in self.undo_commands]
info = [command.__class__.__name__ for command in self.undo_commands]
print(info)
1
if __name__ == '__main__':
controller = RemoteController()
# 要控制起居室的灯
livingRoomLight = Light("Living Room")
# 将livingRoomLight对象传到这个中间件里面,这时这个中间件就和电灯关联了
livingRoomLightOn = LightOnCommand(livingRoomLight)
livingRoomLightOff = LightOffCommand(livingRoomLight)
# 定义一下遥控器的设置,0号槽控制电灯,on按钮是打开起居室的灯,off按钮是关闭起居室的灯
# 这时这个中间件又和遥控器关联了
slot = 0
controller.setCommand(slot, livingRoomLightOn, livingRoomLightOff)
# 开灯关灯重复两次
controller.onButtonWasPress(slot)
controller.offButtonWasPress(slot)
controller.onButtonWasPress(slot)
controller.offButtonWasPress(slot)
def get_command_infos():
print('------当前light状态为:', livingRoomLight.state) # 当前电灯的状态
print('剩余撤销操作:', len(controller.commands)) # 剩余可撤销的操作
print('剩余反撤销操作:', len(controller.undo_commands)) # 还剩3个可以撤销的操作
get_command_infos() # 当前为'关灯'状态 ---- 操作4次后, 有了4个可以撤销的操作
print('-' * 15, '撤销1次')
controller.commands_info() # 打印操作命令的地址, 可以看出是4个不同的命令
controller.undoButtonWasPress() # 撤销后变成了'开灯'状态, 同时还能撤销3次
print('剩余撤销操作:', len(controller.commands)) # 还能执行的撤销操作次数
get_command_infos()
print('*' * 15, '反撤销1次!')
controller.undo_commands_info() # 目前撤销命令队列中有1个撤销操作
controller.undo_undoButtonWasPress() # 反撤销后又变成了'关灯'状态
controller.undo_commands_info() # 目前撤销命令队列中有0个撤销操作, 无法继续反撤销
controller.undo_undoButtonWasPress() # 反撤销失败
get_command_infos()
# 撤销两次
controller.undoButtonWasPress()
controller.undoButtonWasPress()
get_command_infos()
print('*' * 15, '新增操作!')
controller.onButtonWasPress(slot)
get_command_infos()
print('反撤销操作:', len(controller.undo_commands)) # 反撤销的操作变为0, 无法反撤销
print('剩余操作:', len(controller.commands)) # 可以撤销的操作个数变为2个