You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中实现可适配多种输入类型的适配器函数?

高效实现多输入格式适配函数的方案

问题背景

我有多个解决同一问题的函数(各自基于不同算法、具备不同特性),由不同开发者编写,每个函数接受的输入格式各不相同。举个简化案例:所有函数处理的都是一组物品,但:

  • 函数A接受dict类型输入:键为物品名称,值为对应物品的数量
  • 函数B接受list类型输入:每个元素是物品名称,且每种物品仅出现一次

需求是构建一个通用适配器函数,让用户可以用任意输入格式(dict或list)调用任意函数(A或B)。

最初的伪代码实现如下,但存在明显缺陷:当有n种输入格式时,需要编写n²个判断分支,扩展性极差:

def adapter(func:callable, input:any):
    if (input is a dict and func expects a dict):
       return func(input)
    elif (input is a list and func expects a list):
       return func(input)
    elif (input is a list and func expects a dict):
       return func({key:1 for key in list})  # convert list to dict
    elif (input is a dict and func expects a list):
       return func(list(input.keys()))  # convert dict to list
    else:
       raise TypeError

高效解决方案:用格式转换注册表替代硬编码判断

核心思路是拆分适配逻辑,将“标记函数期望格式”和“格式转换规则”分离,避免大量if-else分支。

1. 给函数标记期望的输入格式

用装饰器为每个函数添加元数据,明确其期望的输入类型:

def expects_input_type(input_type):
    def decorator(func):
        func.expected_input = input_type
        return func
    return decorator

# 标记函数A期望dict类型输入
@expects_input_type(dict)
def funcA(items_dict):
    return sum(items_dict.values())  # 示例逻辑:计算总物品数量

# 标记函数B期望list类型输入
@expects_input_type(list)
def funcB(items_list):
    return len(items_list)  # 示例逻辑:统计物品种类数

2. 维护格式转换注册表

创建一个字典存储格式转换规则,键为(源格式类型, 目标格式类型)的元组,值为对应的转换函数:

# 格式转换注册表:(源类型, 目标类型) → 转换函数
converters = {
    (list, dict): lambda lst: {item: 1 for item in lst},  # list转dict,默认数量为1
    (dict, list): lambda dct: list(dct.keys()),  # dict转list,取所有物品名称
    (dict, dict): lambda x: x,  # 格式一致时直接返回
    (list, list): lambda x: x
}

3. 实现通用适配器函数

核心逻辑简化为:获取函数期望格式→查找转换规则→转换输入→调用函数:

def adapter(func, input_data):
    input_type = type(input_data)
    target_type = getattr(func, 'expected_input', None)
    
    if not target_type:
        raise TypeError("函数未标记期望的输入格式")
    
    # 查找对应的转换函数
    convert_func = converters.get((input_type, target_type))
    if not convert_func:
        raise TypeError(f"不支持从{input_type.__name__}转换到{target_type.__name__}")
    
    # 转换输入并调用原函数
    converted_input = convert_func(input_data)
    return func(converted_input)

实际使用示例

# 用dict调用期望list的funcB
print(adapter(funcB, {"apple": 2, "banana": 3}))  # 输出:2

# 用list调用期望dict的funcA
print(adapter(funcA, ["apple", "banana"]))  # 输出:2

扩展优势

  • 新增输入格式时,仅需两步:
    1. 给新函数用expects_input_type标记目标格式
    2. 在converters中添加对应的转换规则(例如新增set格式,只需补充(set, dict)、(dict, set)等转换函数)
  • 无需修改适配器核心代码,完全符合开闭原则,扩展性极强

内容的提问来源于stack exchange,提问作者Erel Segal-Halevi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 23:05:34