什么是python中的工厂函数

什么是工厂函数?

用函数来创建并返回对象或可调用物(函数/类实例/配置好的函数),把“怎么建、建什么”封装起来,对调用方只暴露一个统一入口。它是“工厂模式”的一种轻量 Python 实现。

1)最常见:对象工厂(替代直接 new)

class MySQL:  ...
class Postgres: ...

def make_db(kind: str, **cfg):
    if kind == "mysql":
        return MySQL(**cfg)
    if kind == "pg":
        return Postgres(**cfg)
    raise ValueError(f"unknown db kind: {kind}")

db = make_db("pg", host="127.0.0.1")

好处:屏蔽实现差异、集中校验与默认参数、便于切换和测试(可注入假实现)。

2)函数工厂(闭包返回“配置好”的函数)

def make_power(n: int):
    def f(x: float) -> float:
        return x ** n   # 捕获 n
    return f

square = make_power(2)
print(square(3))  # 9

场景:按配置生成处理器/校验器/中间件(计时、重试、限流等)。

3)注册表(插件式工厂,最常用在实际项目)

_REGISTRY: dict[str, type] = {}

def register(name: str):
    def deco(cls):
        _REGISTRY[name] = cls
        return cls
    return deco

@register("mysql")
class MySQL: ...
@register("pg")
class Postgres: ...

def make_db(kind: str, **cfg):
    try:
        return _REGISTRY[kind](**cfg)
    except KeyError:
        raise ValueError(f"unknown kind: {kind}")

优点:新增实现只需 @register,无需改工厂函数——开放封闭。

4)类工厂(动态生成类)

def make_model_class(name: str, base=object):
    return type(name, (base,), {"version": 1})

UserV1 = make_model_class("UserV1")

用途:元编程/ORM/动态协议适配。

5)partial 当“函数工厂”

from functools import partial

def connect(host, port, timeout):
    ...

fast_connect = partial(connect, timeout=1.0)  # 预配置一部分参数

6)与标准库的工厂位姿:default_factory

from dataclasses import dataclass, field

@dataclass
class Bag:
    items: list[int] = field(default_factory=list)  # 避免可变默认值坑

何时用工厂函数?
• 需要按配置或标识创建不同实现(数据库、存储、模型客户端)。
• 想要隐藏复杂构造(校验、默认值、依赖装配)。
• 需要可测试性/可替换性(注入 stub/mock)。
• 做插件化架构(注册表工厂)。

小坑与建议
• 错误提示要清晰:未知类型抛 ValueError,列出可选值。
• 避免分支爆炸:超过 3–4 个实现就改用“注册表模式”。
• 闭包晚绑定:工厂返回的函数若在循环中创建,注意用默认参数或额外一层函数定格变量。
• 类型提示:用 typing.Protocol 或 Union 标注返回类型,便于 mypy/pyright 检查。

from typing import Protocol

class DB(Protocol):
    def query(self, sql: str) -> list: ...

def make_db(kind: str) -> DB: ...

——
一句话:工厂函数=“把创建细节装进函数”。它让调用方只关心“要什么”,而不用关心“怎么造”,非常适合可插拔、可测试的 Python 代码风格。

<think> 我们首先需要明确用户的问题:用户想了解Python工厂函数的定义、使用方法及示例。 根据提供的引用内容,我们可以整理出关于工厂函数/工厂模式的相关信息: 1. 引用[1]展示了通过工厂函数创建专用函数的例子:使用外部函数生成具有不同指数的幂函数。 2. 引用[2][3]提到了类方法作为工厂方法的使用,例如作为替代构造函数(frombirthyear)和工厂模式(根据参数返回不同实例)。 3. 引用[4]展示了一个简单的工厂类,通过get_instance方法根据传入的类来创建实例。 4. 引用[5]则展示了使用鸭子类型和工厂函数(choose_duck)来根据字符串参数返回不同鸭子的实例。 因此,我们可以将工厂函数的概念分为两种: - 工厂函数:普通函数,用于返回特定对象(函数或类的实例)。 - 工厂模式:一种设计模式,通过一个工厂类或工厂方法根据输入参数来创建不同类型的对象。 在回答中,我们要涵盖: 1. 定义:工厂函数是一个创建并返回其他对象的函数。它可以是普通函数,也可以是类方法(如类工厂方法)。工厂模式是使用工厂函数工厂类来封装对象创建过程的设计模式。 2. 使用方法:通常通过定义一个函数,在函数内部根据参数决定创建和返回哪个对象。 3. 示例:提供多个示例,包括创建函数工厂、作为替代构造函数的类方法、工厂类以及根据参数返回不同子类实例的工厂函数。 另外,注意引用标识的添加:在回答中引用了提供的引用内容,需要在引用的段落末尾添加引用标识,如[^1]、[^2]等。 根据上述整理,我们组织回答如下: </think> ### Python工厂函数的定义、使用方法及示例 #### 1. 定义 工厂函数是一种**创建型设计模式**,核心思想是通过一个统一的接口动态创建不同类型的对象实例。它将**对象实例化的逻辑封装**在函数内部,调用者只需传入简单参数(如类型标识),无需了解具体创建细节[^1][^4]。这种模式实现了**创建逻辑与使用逻辑的解耦**,提高了代码的灵活性和可维护性[^2]。 #### 2. 使用方法 1. **创建工厂函数**:定义函数接收参数(如类型标识) 2. **封装创建逻辑**:在函数内部根据参数决定实例化哪个类 3. **返回对象实例**:返回创建好的对象供调用者使用 ```python def factory_function(参数): if 参数 == "类型A": return 类A() elif 参数 == "类型B": return 类B() ``` #### 3. 核心优势 - **降低耦合度**:调用方无需关注对象具体类 - **扩展性强**:新增类型只需修改工厂函数 - **简化调用**:统一创建接口,避免重复代码[^1][^4] - **支持数据封装**:隐藏对象创建细节[^1] #### 4. 典型示例 **(1)基础工厂函数** ```python def shape_factory(shape_type): if shape_type == "circle": class Circle: # 圆形类 def draw(self): print("绘制圆形") return Circle() elif shape_type == "square": class Square: # 方形类 def draw(self): print("绘制方形") return Square() # 使用工厂 circle = shape_factory("circle") circle.draw() # 输出:绘制圆形 ``` **(2)类方法实现工厂模式** ```python class Person: def __init__(self, name, age): self.name = name self.age = age @classmethod def from_birthyear(cls, name, birth_year): # 替代构造的工厂方法 age = 2024 - birth_year # 动态计算年龄 return cls(name, age) # 返回实例化对象 # 使用工厂方法创建实例 person = Person.from_birthyear("Alice", 1990) print(f"{person.name} 年龄: {person.age}") # 输出:Alice 年龄: 34[^2] ``` **(3)类型映射工厂** ```python class Cat: def speak(self): print("喵喵叫") class Dog: def speak(self): print("汪汪叫") def animal_factory(animal_type): type_map = { # 类型映射字典 "cat": Cat, "dog": Dog } return type_map[animal_type]() # 动态实例化 # 使用工厂 pet = animal_factory("dog") pet.speak() # 输出:汪汪叫[^4] ``` **(4)带参数的函数工厂** ```python def power_factory(exponent): # 生成幂函数工厂 def power(base): return base ** exponent # 闭包保留指数参数 return power # 创建特定幂函数 square = power_factory(2) cube = power_factory(3) print(square(4)) # 输出:16 (4²) print(cube(4)) # 输出:64 (4³)[^1] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值