news 2026/7/7 14:37:52

Python语言之“工厂函数“”与“多态方式”的异同分析探究!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python语言之“工厂函数“”与“多态方式”的异同分析探究!

Python语言之“工厂函数“”与“多态方式”的异同分析探究!
工厂函数确实常常利用多态来创建对象,但它们不是同一个概念

让我用对比的方式解释:

1.相同点:都涉及多种类型

# 多态:不同类型响应相同的方法classAnimal:defmake_sound(self):passclassDog(Animal):defmake_sound(self):return"Woof!""""十一剑的CS_DN博客"""classCat(Animal):defmake_sound(self):return"Meow!"# 工厂函数:创建不同类型的对象defcreate_animal(animal_type):ifanimal_type=="dog":returnDog()elifanimal_type=="cat":returnCat()

2.关键区别

a. 关注点不同

# 多态:关注"行为"的多样性classPaymentMethod:defpay(self,amount):passclassCreditCard(PaymentMethod):defpay(self,amount):print(f"信用卡支付 ${amount}")"""十一剑的CS_DN博客"""classPayPal(PaymentMethod):defpay(self,amount):print(f"PayPal支付 ${amount}")# 工厂函数:关注"创建"的多样性classPaymentFactory:defcreate_payment(self,method):ifmethod=="credit_card":returnCreditCard()elifmethod=="paypal":returnPayPal()# 客户端代码使用多态defprocess_payment(payment_method,amount):payment_method.pay(amount)# 多态:不同支付方式统一接口# 使用工厂创建对象factory=PaymentFactory()payment=factory.create_payment("credit_card")process_payment(payment,100)# 然后使用多态调用

b. 时间点不同

# 多态:发生在运行时(动态绑定)classShape:defdraw(self):pass"""十一剑的CS_DN博客"""classCircle(Shape):defdraw(self):print("绘制圆形")classSquare(Shape):defdraw(self):print("绘制方形")# 工厂函数:在创建时就决定了类型defcreate_shape(shape_type):ifshape_type=="circle":returnCircle()# 创建时就确定了是圆形elifshape_type=="square":returnSquare()# 创建时就确定了是方形# 多态:调用时才确定具体行为shapes=[create_shape("circle"),create_shape("square")]forshapeinshapes:shape.draw()# 多态:运行时才知道调用哪个draw方法

3.更清晰的对比表

特性多态工厂函数
主要目的统一接口,不同实现创建对象
关注点对象的行为对象的创建
时间点运行时(方法调用时)创建时(对象实例化时)
核心机制继承 + 方法重写条件判断 + 构造函数调用
代码位置类的定义中独立的函数或类中

4.工厂函数内部如何使用多态

fromabcimportABC,abstractmethod# 1. 定义接口(多态的基础)classLogger(ABC):@abstractmethoddeflog(self,message):pass"""十一剑的CS_DN博客"""# 2. 具体实现(多态的具体表现)classFileLogger(Logger):deflog(self,message):withopen("app.log","a")asf:f.write(message+"\n")classConsoleLogger(Logger):deflog(self,message):print(f"[LOG]{message}")classDatabaseLogger(Logger):deflog(self,message):# 模拟数据库写入print(f"写入数据库:{message}")# 3. 工厂函数(利用多态创建对象)defcreate_logger(logger_type,**kwargs):"""工厂函数,根据类型创建不同的日志器"""iflogger_type=="file":returnFileLogger()eliflogger_type=="console":returnConsoleLogger()eliflogger_type=="database":returnDatabaseLogger()else:# 可以返回默认实现returnConsoleLogger()# 4. 客户端代码(完全基于多态)defprocess_data(data,logger):"""不关心logger的具体类型,只关心它有log方法"""# 处理数据...logger.log(f"开始处理数据:{data}")# 多态调用# 更多处理...logger.log("数据处理完成")# 使用:工厂创建 + 多态使用logger1=create_logger("file")logger2=create_logger("console")process_data("用户数据",logger1)# 写入文件process_data("系统数据",logger2)# 输出到控制台

5.open()函数的具体分析

# open() 函数内部实现(概念上的伪代码)defopen(file,mode='r',**kwargs):# 工厂函数的逻辑:根据条件创建不同对象if'b'inmode:# 二进制模式if'r'inmode:returnBufferedReader(file,**kwargs)# 多态:返回BufferedReaderelif'w'inmode:returnBufferedWriter(file,**kwargs)# 多态:返回BufferedWriterelse:# 文本模式if'r'inmode:returnTextIOWrapper(file,**kwargs,mode='r')# 多态:返回TextIOWrapperelif'w'inmode:returnTextIOWrapper(file,**kwargs,mode='w')# 多态:返回TextIOWrapper# 所有返回的对象都有 read()/write() 等方法(多态的基础)

6.更复杂的例子:工厂函数返回多态对象

# 1. 多态接口classDataStore(ABC):@abstractmethoddefsave(self,key,value):pass@abstractmethoddefload(self,key):pass# 2. 具体实现classFileStore(DataStore):def__init__(self,filename):self.filename=filenamedefsave(self,key,value):withopen(self.filename,'a')asf:f.write(f"{key}:{value}\n")defload(self,key):withopen(self.filename,'r')asf:forlineinf:k,v=line.strip().split(':')ifk==key:returnvreturnNoneclassMemoryStore(DataStore):def__init__(self):self.data={}defsave(self,key,value):self.data[key]=valuedefload(self,key):returnself.data.get(key)# 3. 工厂函数(可以包含更多创建逻辑)defcreate_store(store_type,**config):ifstore_type=="file":returnFileStore(config.get('filename','data.txt'))elifstore_type=="memory":returnMemoryStore()elifstore_type=="redis":# 可以轻松扩展# 假设我们后面添加了RedisStorereturnRedisStore(config.get('host','localhost'))else:raiseValueError(f"不支持的存储类型:{store_type}")# 4. 客户端代码(完全多态)defprocess_user_data(user_id,data,store):"""不关心store的具体类型,只要它有save和load方法"""# 保存数据store.save(f"user_{user_id}",data)# 多态调用# 读取数据loaded=store.load(f"user_{user_id}")# 多态调用returnloaded"""十一剑的CS_DN博客"""# 5. 使用file_store=create_store("file",filename="users.txt")memory_store=create_store("memory")# 相同的接口,不同的实现(多态)result1=process_user_data(1,"Alice",file_store)result2=process_user_data(2,"Bob",memory_store)

敲黑板!!@@!!十一剑的CS_DN博客祝您天天进步!

工厂函数和多态是互补的,常常一起使用

  1. 工厂函数是"创建者"

    • 负责根据条件创建合适的对象
    • 隐藏对象创建的复杂性
  2. 多态是"使用者"

    • 让不同对象可以用相同接口操作
    • 隐藏对象类型的差异性
  3. 典型流程

    工厂函数创建对象 → 对象具有多态接口 → 客户端代码通过多态接口使用对象

总结如下:工厂函数确实常常返回支持多态的对象,这样客户端代码可以统一处理这些对象,而不用关心它们的具体类型。但两者是不同层次的概念

  • 多态是关于接口设计的
  • 工厂函数是关于对象创建的
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 21:42:50

单链表-删除中间节点的应用

思索过程:1.将链表从中间位置断开(变成head->1->2->3和4->5->6两段)2.将后半段的链表逆置(从4->5->6变成6->5->4)3.设置四个指针p1,p2,q1,q2&#xff08…

作者头像 李华
网站建设 2026/7/7 14:31:26

FreeModbus+STM32F407IGT6标准库项目代码

FreeModbus移植的文章比较多了,分享一个移植好可用的代码。 代码连接:STM32F407IGT6移植FreeModbushttps://gitee.com/zhuzheshuai/STM32F407IGT6_FreeModbus 通信使用串口和RS485两种方式,RS485发送/接收使能引脚用的PH9,可以根…

作者头像 李华
网站建设 2026/7/7 11:02:10

拥抱AI,HPE Networking以“自动驾驶的网络”引领智能网络新时代

2025年12月16日,HPE Networking在北京举办以“拥抱AI,构建自动驾驶的网络”为主题的媒体沟通会,首次对外分享了在完成对 Juniper Networks 收购后所推出的全新战略路线:以构建“安全赋能的AI原生网络”为核心举措,打造…

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

基于springboot名老中医传承信息系统设计与开发

基于Spring Boot的名老中医传承信息系统设计与开发是一个结合了现代信息技术和传统中医智慧的综合性项目。以下是对该系统的详细介绍: 一、系统背景与意义 中医作为中华民族的传统医学,承载着丰富的历史文化底蕴与独特的医疗智慧。在历史的长河中&#x…

作者头像 李华
网站建设 2026/7/7 12:24:58

潮玩盲盒二手交易平台

可s我领取源码!!Spring Boot 潮玩盲盒二手交易平台是一款专为潮玩盲盒爱好者打造的线上二手交易系统。借助 Spring Boot 框架的高效性和灵活性,该平台旨在为用户提供便捷、安全且功能丰富的交易环境,促进潮玩盲盒的二手流通,满足玩家对独特潮…

作者头像 李华
网站建设 2026/7/6 3:40:28

除了抓包失败,Burp Suite还有哪些新手常遇到的配置问题?

除了抓包失败,Burp Suite新手还常遇到以下配置问题:一、证书配置问题证书未正确信任是新手最常遇到的HTTPS抓包问题。即使下载了Burp的CA证书,如果未导入到浏览器的"受信任的根证书颁发机构"存储区,浏览器仍会提示"…

作者头像 李华