这里写目录标题
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"])
优点:
- 完全自动化参数提取;
- 无需手动维护参数列表;
- 适合快速原型开发。
总结建议
选择时考虑:
- 如果参数结构简单 → ****kwargs或方法3(参数字典)
- 需要类型安全 → 方法4(dataclasses/pydantic)
- 算法逻辑复杂 → 方法5(策略模式)
- 算法数量多且动态 → 方法6(注册表)或方法7(inspect)