Python 3 无需复制子函数签名自动匹配分发参数的惯用实现方案
Python 3 自动筛选适配子函数参数的惯用实现方案
Python 标准库自带的inspect模块可以直接解析函数签名,是实现该需求的最优方案,无需引入第三方依赖。
工具函数实现
import inspect def wrangle_function_signature(func, *args, **kwargs): # 解析目标函数的签名 sig = inspect.signature(func) params = sig.parameters.values() has_var_args = False # 标记目标函数是否有*args可变位置参数 has_var_kwargs = False # 标记目标函数是否有**kwargs可变关键字参数 fixed_pos_count = 0 # 目标函数固定位置参数的总数 allowed_kw_names = set() # 目标函数支持的关键字参数名集合 for param in params: if param.kind in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD): fixed_pos_count += 1 allowed_kw_names.add(param.name) elif param.kind == param.KEYWORD_ONLY: allowed_kw_names.add(param.name) elif param.kind == param.VAR_POSITIONAL: has_var_args = True elif param.kind == param.VAR_KEYWORD: has_var_kwargs = True # 筛选适配的位置参数 processed_args = args if has_var_args else args[:fixed_pos_count] # 筛选适配的关键字参数 if has_var_kwargs: processed_kwargs = kwargs else: processed_kwargs = {k: v for k, v in kwargs.items() if k in allowed_kw_names} return processed_args, processed_kwargs
使用示例
按你给出的场景,直接替换原有逻辑即可:
def a(x, y, z=0, g=10): print(f"a 收到参数:x={x}, y={y}, z={z}, g={g}") def b(*args): print(f"b 收到参数:{args}") def c(p, q, u=False, *args, **kwargs): a_args, a_kwargs = wrangle_function_signature(a, *args, **kwargs) a(*a_args, **a_kwargs) b_args, b_kwargs = wrangle_function_signature(b, *args, **kwargs) b(*b_args, **b_kwargs) # 测试调用 c("测试p", "测试q", True, 1, 2, 3, g=99, 额外参数="测试值")
运行输出:
a 收到参数:x=1, y=2, z=3, g=99 b 收到参数:(1, 2, 3)
方案说明
- 自动兼容所有Python参数类型:位置参数、默认参数、
*args、关键字-only参数、**kwargs均可正确识别适配 - 完全匹配无参数冲突的场景,不需要额外处理重名参数问题
- 后续新增子函数不需要修改工具逻辑,直接调用即可
内容的提问来源于stack exchange,提问作者SumNeuron
相关产品推荐
相关产品推荐

