news 2026/10/13 14:54:02

Python 命令模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 命令模式

Python 中的命令模式(Command Pattern)

命令模式是一种行为型设计模式,其核心目的是:
将一个请求(操作)封装为一个对象,从而让你可以参数化客户端的不同请求、将请求排队或记录请求日志,还支持可撤销的操作。

形象比喻:就像餐厅点餐——顾客(调用者)向服务员(调用者)下订单(命令对象),服务员把订单交给厨师(接收者)执行。订单可以被保存、排队、甚至取消。

命令模式的优点
  • 解耦调用者和接收者:调用者不需要知道谁来执行命令
  • 支持撤销/重做(Undo/Redo):最经典的应用
  • 支持命令队列、延迟执行、日志记录
  • 易于扩展新命令:符合开闭原则
  • 可以组合命令(宏命令)
典型应用场景
  • GUI 按钮、菜单操作(点击执行命令)
  • 撤销/重做功能(文本编辑器、绘图软件)
  • 事务系统(数据库操作回滚)
  • 任务队列、线程池
  • 宏录制(一系列命令组合执行)
  • 远程控制、日志记录
Python 实现示例:带撤销功能的文本编辑器
fromabcimportABC,abstractmethodfromtypingimportList# 接收者(Receiver):真正执行操作的对象classTextEditor:def__init__(self,text:str=""):self.text=textdefinsert(self,position:int,content:str):self.text=self.text[:position]+content+self.text[position:]print(f"插入文本: '{content}' → 当前文本: '{self.text}'")defdelete(self,start:int,end:int):deleted=self.text[start:end]self.text=self.text[:start]+self.text[end:]print(f"删除文本: '{deleted}' → 当前文本: '{self.text}'")returndeleted# 返回被删除的内容,用于撤销def__str__(self):returnself.text# 命令接口(Command)classCommand(ABC):@abstractmethoddefexecute(self):pass@abstractmethoddefundo(self):pass# 具体命令:插入命令classInsertCommand(Command):def__init__(self,editor:TextEditor,position:int,content:str):self.editor=editor self.position=position self.content=contentdefexecute(self):self.editor.insert(self.position,self.content)defundo(self):# 撤销插入就是删除刚插入的内容self.editor.delete(self.position,self.position+len(self.content))# 具体命令:删除命令classDeleteCommand(Command):def__init__(self,editor:TextEditor,start:int,end:int):self.editor=editor self.start=start self.end=end self.deleted_content=None# 执行时保存被删内容defexecute(self):self.deleted_content=self.editor.delete(self.start,self.end)defundo(self):ifself.deleted_contentisnotNone:self.editor.insert(self.start,self.deleted_content)# 调用者(Invoker):管理命令历史,支持撤销classCommandManager:def__init__(self):self.history:List[Command]=[]self.redo_stack:List[Command]=[]defexecute_command(self,command:Command):command.execute()self.history.append(command)self.redo_stack.clear()# 新命令后,清空重做栈defundo(self):ifnotself.history:print("没有可撤销的操作")returncommand=self.history.pop()command.undo()self.redo_stack.append(command)print("撤销成功")defredo(self):ifnotself.redo_stack:print("没有可重做的操作")returncommand=self.redo_stack.pop()command.execute()self.history.append(command)print("重做成功")# 客户端使用if__name__=="__main__":editor=TextEditor("Hello World")manager=CommandManager()print(f"初始文本: '{editor}'\n")# 执行插入insert_cmd=InsertCommand(editor,5,", Python")manager.execute_command(insert_cmd)# 输出: Hello, Python World# 执行删除delete_cmd=DeleteCommand(editor,5,13)# 删除 ", Python"manager.execute_command(delete_cmd)# 输出: Hello Worldprint("\n--- 开始撤销 ---")manager.undo()# 撤销删除 → 恢复 ", Python"manager.undo()# 撤销插入 → 回到 "Hello World"print("\n--- 开始重做 ---")manager.redo()# 重做插入manager.redo()# 重做删除

输出示例:

初始文本: 'Hello World' 插入文本: ', Python' → 当前文本: 'Hello, Python World' 删除文本: ', Python' → 当前文本: 'Hello World' --- 开始撤销 --- 撤销成功 # 恢复到 Hello, Python World 撤销成功 # 恢复到 Hello World --- 开始重做 --- 重做成功 # 插入 → Hello, Python World 重做成功 # 删除 → Hello World
Pythonic 简化版:函数作为命令

当命令简单时,可以用 callable(函数/闭包)代替类:

classSimpleCommandManager:def__init__(self):self.history=[]self.redo_stack=[]defexecute(self,do_func,undo_func):do_func()self.history.append((do_func,undo_func))self.redo_stack.clear()defundo(self):ifself.history:do_func,undo_func=self.history.pop()undo_func()self.redo_stack.append((do_func,undo_func))defredo(self):ifself.redo_stack:do_func,undo_func=self.redo_stack.pop()do_func()self.history.append((do_func,undo_func))# 使用text="Hello"manager=SimpleCommandManager()definsert():nonlocaltext text+=" World"print("→",text)defremove():nonlocaltext text=text[:-6]print("←",text)manager.execute(insert,remove)manager.execute(lambda:print("额外操作"),lambda:None)manager.undo()manager.undo()manager.redo()
命令模式结构总结
角色说明
Command抽象命令接口(execute/undo)
ConcreteCommand具体命令(InsertCommand、DeleteCommand)
Receiver接收者(TextEditor)
Invoker调用者(CommandManager)
Client创建命令并设置到调用者
命令模式 vs 其他模式对比
模式目的是否支持撤销典型场景
命令封装请求,支持撤销/队列是编辑器、事务、宏
策略算法可替换否支付、排序
观察者状态变化广播通知否事件监听
责任链请求沿链传递否处理流程
Python 中的实用建议
  • 简单命令:用 lambda 或函数闭包(最 Pythonic)
  • 复杂命令:用类实现,支持状态保存
  • 宏命令:创建一个 CompositeCommand,内部持有多个子命令
  • 常与观察者模式结合(命令执行后通知 UI 更新)
classMacroCommand(Command):def__init__(self,commands:List[Command]):self.commands=commandsdefexecute(self):forcmdinself.commands:cmd.execute()defundo(self):forcmdinreversed(self.commands):cmd.undo()

命令模式是实现可撤销操作和操作历史的基石,在编辑器、游戏存档、事务系统中广泛应用。

如果你想看更多实战例子(如 GUI 按钮命令、线程池任务队列、宏录制、结合队列的延迟执行),或者如何与备忘录模式结合实现多级撤销,欢迎继续问!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 17:28:40

TeslaMate完整搭建指南:快速构建免费特斯拉数据分析平台

TeslaMate完整搭建指南:快速构建免费特斯拉数据分析平台 【免费下载链接】teslamate 项目地址: https://gitcode.com/gh_mirrors/tes/teslamate 想要深入了解你的特斯拉性能表现吗?TeslaMate作为开源自托管解决方案,能够帮助你全面监…

作者头像 李华
网站建设 2026/10/10 3:05:19

IINA终极指南:macOS视频播放器的10个高效使用方案

IINA终极指南:macOS视频播放器的10个高效使用方案 【免费下载链接】iina 项目地址: https://gitcode.com/gh_mirrors/iin/iina 您是否曾经为在macOS上找不到理想的视频播放器而烦恼?当您需要播放多种格式的视频文件、管理复杂的字幕需求&#xf…

作者头像 李华
网站建设 2026/10/10 3:05:25

Open-AutoGLM悄然崛起:与ChatGLM的4个关键区别你必须掌握

第一章:Open-AutoGLM与ChatGLM的演进背景近年来,随着大规模语言模型技术的快速发展,自然语言处理在多个领域实现了突破性进展。其中,ChatGLM系列模型作为智谱AI推出的高性能双语对话模型,凭借其基于GLM(Gen…

作者头像 李华
网站建设 2026/10/12 16:26:33

AutoAWQ深度解析:大模型量化加速的完整解决方案

AutoAWQ深度解析:大模型量化加速的完整解决方案 【免费下载链接】AutoAWQ AutoAWQ implements the AWQ algorithm for 4-bit quantization with a 2x speedup during inference. 项目地址: https://gitcode.com/gh_mirrors/au/AutoAWQ 还在为大型语言模型的高…

作者头像 李华
网站建设 2026/10/9 19:07:18

为什么越来越多开发者选择Dify进行Agent开发?

为什么越来越多开发者选择 Dify 进行 Agent 开发? 在企业智能化浪潮席卷各行各业的今天,AI 不再只是实验室里的前沿技术,而是真正走进了客服窗口、内容工厂和内部知识系统。尤其是以大语言模型(LLM)为核心的 AI Agent …

作者头像 李华
网站建设 2026/10/10 18:59:35

专业级iOS设备越狱:palera1n工具深度解析与实战指南

在iOS生态系统的安全研究领域,设备越狱始终占据着重要地位。本文将为技术爱好者和安全研究人员深入剖析palera1n越狱工具的技术架构、操作原理及实战应用,帮助您全面掌握这一专业级越狱解决方案。 【免费下载链接】palera1n Jailbreak for arm64 devices…

作者头像 李华