news 2026/9/2 2:07:51

Python 适配器模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 适配器模式

Python 中的适配器模式(Adapter Pattern)

适配器模式是一种结构型设计模式,其核心目的是:
将一个类的接口转换成客户端期望的另一个接口,让原本由于接口不兼容而无法一起工作的类可以协同工作。

形象比喻:就像电源适配器(将欧标插头转换成美标插座),它不改变原有功能,只做接口转换。

两种形式
  1. 类适配器(通过多重继承实现)—— 在 Python 中较少用,因为 Python 支持多继承,但不推荐过度使用。
  2. 对象适配器(通过组合实现)——Python 中最推荐的方式,更灵活、更符合“组合优于继承”原则。
典型应用场景
  • 使用第三方库,但其接口与你的代码不匹配
  • 整合遗留系统(老代码接口过时)
  • 需要统一不同数据源的接口(如不同 API 返回格式)
  • 想复用现有类,但接口不一致
Python 示例:对象适配器(推荐)

假设我们有一个老的支付系统OldPaymentSystem,它的方法是make_payment(amount)
现在引入一个新的第三方支付网关NewPaymentGateway,方法是pay(amount, currency)
我们想让客户端代码统一使用pay(amount, currency)接口。

# 被适配的类(Adaptee)—— 老系统classOldPaymentSystem:defmake_payment(self,amount):print(f"Old system: Processing payment of ${amount}")returnTrue# 目标接口(Target)—— 客户端期望的接口classPaymentProcessor:defpay(self,amount,currency="USD"):raiseNotImplementedError# 适配器(Adapter)—— 通过组合将老系统适配到新接口classOldSystemAdapter(PaymentProcessor):def__init__(self,old_system:OldPaymentSystem):self.old_system=old_systemdefpay(self,amount,currency="USD"):# 转换接口:忽略 currency(老系统不支持),直接调用 make_paymentprint(f"Adapter: Converting pay({amount},{currency}) to make_payment({amount})")returnself.old_system.make_payment(amount)# 新的支付网关(另一个实现)classNewPaymentGateway(PaymentProcessor):defpay(self,amount,currency="USD"):print(f"New gateway: Processing{currency}{amount}payment securely")returnTrue# 客户端代码(统一使用 PaymentProcessor 接口)defprocess_payment(processor:PaymentProcessor,amount:float):processor.pay(amount,"USD")# 使用示例if__name__=="__main__":# 使用新网关new_gateway=NewPaymentGateway()process_payment(new_gateway,100.0)# 使用老系统(通过适配器)old_system=OldPaymentSystem()adapter=OldSystemAdapter(old_system)process_payment(adapter,200.0)

输出

New gateway: Processing USD 100.0 payment securely Adapter: Converting pay(200.0, USD) to make_payment(200.0) Old system: Processing payment of $200.0

客户端代码完全不需要知道底层是新网关还是老系统。

类适配器示例(了解即可,不推荐)
classOldSystemClassAdapter(OldPaymentSystem,PaymentProcessor):defpay(self,amount,currency="USD"):# 直接调用继承来的 make_paymentreturnself.make_payment(amount)# 使用adapter=OldSystemClassAdapter()adapter.pay(150.0)

缺点:Python 多继承容易导致复杂性,且无法适配已有实例。

更实用的例子:JSON API 适配器

假设有两个 API 返回不同格式的数据,我们想统一成get_user_info()返回标准字典。

importjson# 旧 API 返回 XML 字符串classLegacyUserAPI:deffetch_user(self,user_id):# 模拟返回 XMLreturnf"<user><id>{user_id}</id><name>John Doe</name><email>john@example.com</email></user>"# 新 API 返回 JSONclassModernUserAPI:defget_user(self,user_id):return{"id":user_id,"name":"Jane Doe","email":"jane@example.com"}# 目标接口classUserService:defget_user_info(self,user_id):raiseNotImplementedError# 适配器:将旧 API 转为标准接口classLegacyAPIAdapter(UserService):def__init__(self,legacy_api:LegacyUserAPI):self.legacy_api=legacy_apidefget_user_info(self,user_id):xml_data=self.legacy_api.fetch_user(user_id)# 简单解析 XML(实际可用 xml.etree.ElementTree)importre data={"id":re.search(r"<id>(.*?)</id>",xml_data).group(1),"name":re.search(r"<name>(.*?)</name>",xml_data).group(1),"email":re.search(r"<email>(.*?)</email>",xml_data).group(1),}returndata# 客户端统一调用defdisplay_user(service:UserService,user_id):info=service.get_user_info(user_id)print(f"User:{info['name']}({info['email']})")# 测试legacy_adapter=LegacyAPIAdapter(LegacyUserAPI())modern_service=ModernUserAPI()display_user(legacy_adapter,123)# 通过适配器使用旧 API# display_user(modern_service, 456) # 如果也适配成 UserService
适配器模式结构总结
角色说明
Target客户端期望的接口(PaymentProcessor)
Client使用 Target 接口的代码
Adaptee需要被适配的原有类(OldPaymentSystem)
Adapter实现 Target,内部持有 Adaptee
优点
  • 解耦客户端与具体实现
  • 复用遗留代码
  • 符合开闭原则(扩展新适配器不修改原有代码)
缺点
  • 引入额外类,略微增加复杂度
  • 如果适配逻辑复杂,可能影响性能
Python 中的实用建议
  • 优先使用对象适配器(组合)
  • 在处理第三方库时非常常见(如不同日志库、缓存客户端、消息队列等)
  • 结合abc模块定义抽象目标接口更清晰
  • 很多时候可以用简单函数或装饰器实现轻量适配,不必每次都建类

如果你想看更多实际案例(如适配不同数据库客户端、日志系统、缓存 Redis vs Memcached),或者与其他模式结合使用,欢迎继续问!

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

openmv与stm32通信实时性分析:STM32F4性能测试报告

OpenMV与STM32通信实时性实测&#xff1a;如何榨干STM32F4的串口性能&#xff1f;你有没有遇到过这种情况——OpenMV明明“咔嚓”一下就识别出了目标&#xff0c;但你的小车却慢半拍地转向&#xff1f;或者AGV在避障时突然抖了一下&#xff0c;像是卡顿了一帧视觉&#xff1f;别…

作者头像 李华
网站建设 2026/9/2 7:00:04

Dify平台的会话上下文长度管理策略

Dify平台的会话上下文长度管理策略 在构建智能客服、AI助手或内容生成系统时&#xff0c;你是否曾遇到这样的尴尬&#xff1a;用户刚聊到第三轮&#xff0c;AI突然“失忆”&#xff0c;忘了之前说好的角色设定&#xff1b;或者更糟——请求直接报错&#xff0c;提示“上下文过长…

作者头像 李华
网站建设 2026/8/29 6:06:57

Open-AutoGLM性能提升5倍的秘密:动态图学习机制深度剖析

第一章&#xff1a;Open-AutoGLM性能提升5倍的秘密&#xff1a;动态图学习机制深度剖析Open-AutoGLM 在图神经网络&#xff08;GNN&#xff09;领域实现了高达5倍的性能提升&#xff0c;其核心突破在于引入了创新的动态图学习机制。该机制不再依赖静态图结构&#xff0c;而是根…

作者头像 李华
网站建设 2026/8/27 5:51:13

图文转Word自动化文档生成终极指南:一键生成,效率翻倍

还在为图文排版抓狂吗&#xff1f;会议记录、产品说明、培训材料...每次都要花几个小时复制粘贴、调整格式&#xff1f;今天我要为你分享一个3分钟搞定图文转Word的方法&#xff0c;让你彻底告别手动排版的烦恼&#xff01; 【免费下载链接】Awesome-Dify-Workflow 分享一些好用…

作者头像 李华
网站建设 2026/8/27 5:54:26

IDM激活脚本完整使用指南:三步实现永久试用期锁定

IDM激活脚本完整使用指南&#xff1a;三步实现永久试用期锁定 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 还在为Internet Download Manager试用期到期而烦恼…

作者头像 李华
网站建设 2026/8/31 19:05:29

5分钟快速上手:Sun-Panel打造终极NAS导航中心

5分钟快速上手&#xff1a;Sun-Panel打造终极NAS导航中心 【免费下载链接】sun-panel 一个NAS导航面板、Homepage、浏览器首页。 项目地址: https://gitcode.com/gh_mirrors/su/sun-panel 想要让你的NAS管理更高效、界面更个性化吗&#xff1f;Sun-Panel作为一款开源的N…

作者头像 李华