Python多算法函数灵活传参设计方法

def main(
	algorithm: str = "sop_mac",
	dataset: str = "ComplexOR",
	prob_name: str | int = "aircraft_assignment",
):

其中algorithm不同,传入的参数也不同。如sop_mac1和sop_mac2传参不同,为了处理不同算法需要不同参数的情况,可以使用以下几种方法,从快速原型开发到大型项目架构设计,帮助开发者平衡代码的灵活性与健壮性,提升可维护性和扩展性。

方法1:使用 **kwargs 接受可变参数

def main(
    algorithm: str = "sop_mac",
    dataset: str = "ComplexOR",
    prob_name: str | int = "aircraft_assignment",
    **kwargs
):
    if algorithm == "sop_mac1":
        param1 = kwargs.get("param1", default_value1)
        param2 = kwargs.get("param2", default_value2)
        # 使用sop_mac1特定的参数
    elif algorithm == "sop_mac2":
        param3 = kwargs.get("param3", default_value3)
        param4 = kwargs.get("param4", default_value4)
        # 使用sop_mac2特定的参数
    # 其他处理...

方法2:使用单独的参数

def main(
    algorithm: str = "sop_mac",
    dataset: str = "ComplexOR",
    prob_name: str | int = "aircraft_assignment",
    # sop_mac1专用参数
    param1: Optional[Type] = None,
    param2: Optional[Type] = None,
    # sop_mac2专用参数
    param3: Optional[Type] = None,
    param4: Optional[Type] = None,
):
    if algorithm == "sop_mac1":
        if param1 is None or param2 is None:
            raise ValueError("sop_mac1 requires param1 and param2")
        # 使用param1和param2
    elif algorithm == "sop_mac2":
        if param3 is None or param4 is None:
            raise ValueError("sop_mac2 requires param3 and param4")
        # 使用param3和param4

方法3:使用参数类/字典

def main(
    algorithm: str = "sop_mac",
    dataset: str = "ComplexOR",
    prob_name: str | int = "aircraft_assignment",
    algorithm_params: Optional[dict] = None,
):
    if algorithm == "sop_mac1":
        params = algorithm_params or {}
        param1 = params.get("param1", default1)
        param2 = params.get("param2", default2)
    elif algorithm == "sop_mac2":
        params = algorithm_params or {}
        param3 = params.get("param3", default3)
        param4 = params.get("param4", default4)

方法4:使用 dataclasses 或 pydantic 模型(类型安全)

为每种算法定义专用的参数类,通过类型系统确保参数正确性:

from dataclasses import dataclass
from typing import Union

# 定义不同算法的参数类
@dataclass
class SopMac1Params:
    param1: int
    param2: str

@dataclass
class SopMac2Params:
    param3: float
    param4: list[str]

def main(
    algorithm: str = "sop_mac",
    dataset: str = "ComplexOR",
    prob_name: Union[str, int] = "aircraft_assignment",
    algorithm_params: Union[SopMac1Params, SopMac2Params, None] = None,
):
    if algorithm == "sop_mac1":
        if not isinstance(algorithm_params, SopMac1Params):
            raise ValueError("sop_mac1 requires SopMac1Params")
        print(f"Running sop_mac1 with {algorithm_params.param1}, {algorithm_params.param2}")
    elif algorithm == "sop_mac2":
        if not isinstance(algorithm_params, SopMac2Params):
            raise ValueError("sop_mac2 requires SopMac2Params")
        print(f"Running sop_mac2 with {algorithm_params.param3}, {algorithm_params.param4}")

# 调用示例
main("sop_mac1", algorithm_params=SopMac1Params(param1=10, param2="test"))
main("sop_mac2", algorithm_params=SopMac2Params(param3=3.14, param4=["a", "b"]))

优点:

  • 类型安全,IDE可自动补全参数;
  • 参数结构清晰,避免字典键错误;
  • 支持默认值和验证逻辑(结合pydantic更强大)。

方法5:策略模式(面向对象)

将不同算法的实现和参数封装到单独的类中:

from abc import ABC, abstractmethod

class Algorithm(ABC):
    @abstractmethod
    def run(self):
        pass

class SopMac1(Algorithm):
    def __init__(self, param1: int, param2: str):
        self.param1 = param1
        self.param2 = param2

    def run(self):
        print(f"SopMac1 executed with {self.param1}, {self.param2}")

class SopMac2(Algorithm):
    def __init__(self, param3: float, param4: list):
        self.param3 = param3
        self.param4 = param4

    def run(self):
        print(f"SopMac2 executed with {self.param3}, {self.param4}")

def main(
    algorithm: Algorithm,  # 直接传入算法实例
    dataset: str = "ComplexOR",
    prob_name: str | int = "aircraft_assignment",
):
    algorithm.run()

# 调用示例
main(SopMac1(param1=10, param2="test"))
main(SopMac2(param3=3.14, param4=["a", "b"]))

优点:

  • 符合开闭原则(新增算法无需修改main函数);
  • 算法逻辑和参数绑定在一起,内聚性更高;
  • 易于扩展(例如添加公共的validate_params方法)。

方法6:使用函数注册表(动态分发)

通过字典动态映射算法名到对应的处理函数:

from typing import Callable, Any

def _handle_sop_mac1(param1: int, param2: str, **kwargs):
    print(f"Handling sop_mac1 with {param1}, {param2}")

def _handle_sop_mac2(param3: float, param4: list, **kwargs):
    print(f"Handling sop_mac2 with {param3}, {param4}")

# 注册表和参数要求
ALGORITHM_REGISTRY = {
    "sop_mac1": {
        "handler": _handle_sop_mac1,
        "required_params": ["param1", "param2"],
    },
    "sop_mac2": {
        "handler": _handle_sop_mac2,
        "required_params": ["param3", "param4"],
    }
}

def main(
    algorithm: str = "sop_mac",
    dataset: str = "ComplexOR",
    prob_name: str | int = "aircraft_assignment",
    **kwargs
):
    if algorithm not in ALGORITHM_REGISTRY:
        raise ValueError(f"Unknown algorithm: {algorithm}")
    
    handler_info = ALGORITHM_REGISTRY[algorithm]
    required_params = handler_info["required_params"]
    
    # 检查必需参数
    missing_params = [p for p in required_params if p not in kwargs]
    if missing_params:
        raise ValueError(f"Algorithm {algorithm} requires: {missing_params}")
    
    # 调用对应的处理函数
    handler_info["handler"](**kwargs)

# 调用示例
main("sop_mac1", param1=10, param2="test")
main("sop_mac2", param3=3.14, param4=["a", "b"])

优点:

  • 动态性强,易于维护(新增算法只需更新注册表);
  • 可集中管理参数依赖关系;
  • 适合插件化架构。

方法7:使用 inspect 模块(自动提取参数)

动态检查处理函数的参数签名,自动提取需要的参数:

import inspect

def sop_mac1(param1: int, param2: str):
    print(f"sop_mac1: {param1}, {param2}")

def sop_mac2(param3: float, param4: list):
    print(f"sop_mac2: {param3}, {param4}")

def main(
    algorithm: str = "sop_mac",
    dataset: str = "ComplexOR",
    prob_name: str | int = "aircraft_assignment",
    **kwargs
):
    # 通过算法名获取对应的函数
    handler = globals().get(algorithm)
    if not handler:
        raise ValueError(f"Unknown algorithm: {algorithm}")
    
    # 获取函数参数列表
    sig = inspect.signature(handler)
    required_params = list(sig.parameters.keys())
    
    # 从kwargs提取所需的参数
    params = {k: kwargs[k] for k in required_params if k in kwargs}
    
    # 检查是否缺少必需参数
    missing_params = [p for p in required_params if p not in params]
    if missing_params:
        raise ValueError(f"Missing params for {algorithm}: {missing_params}")
    
    handler(**params)

# 调用示例
main("sop_mac1", param1=10, param2="test")
main("sop_mac2", param3=3.14, param4=["a", "b"])

优点:

  • 完全自动化参数提取;
  • 无需手动维护参数列表;
  • 适合快速原型开发。

总结建议

选择时考虑:

  1. 如果参数结构简单 → ****kwargs或方法3(参数字典)
  2. 需要类型安全 → 方法4(dataclasses/pydantic)
  3. 算法逻辑复杂 → 方法5(策略模式)
  4. 算法数量多且动态 → 方法6(注册表)或方法7(inspect)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值