Python函数调用时如何简化同名参数传递避免冗余写法
问题场景
现有两个固定参数列表的函数func10(接收10个参数a1a10)、`func11`(接收11个参数a1a11),func11内部需要调用func10,且a1~a10需要按同名关键字传入func10,要求支持调用func11时任意调整关键字参数顺序,同时避免手写a1=a1, a2=a2...这类冗余传参代码。
初始冗余实现如下:
def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10): return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11): return a11 + func10(a1=a1, a2=a2, a3=a3, a4=a4, a5=a5, a6=a6, a7=a7, a8=a8, a9=a9, a10=a10)
推荐实现方案
最稳妥、完全适配需求的方案是结合标准库inspect获取被调用函数的参数签名,自动从当前函数的入参中筛选同名参数传递,既保留显式参数列表的IDE提示、静态检查能力,又完全支持乱序传参,没有冗余代码。
import inspect def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10): return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 # 提前缓存func10的参数名集合,避免每次调用都重复解析签名,性能和手写传参几乎无差 _FUNC10_PARAMS = set(inspect.signature(func10).parameters.keys()) def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11): # 获取当前作用域所有绑定的入参,精确筛选出func10需要的参数 current_params = locals() func10_kwargs = {k: current_params[k] for k in _FUNC10_PARAMS} return a11 + func10(**func10_kwargs) # 测试:任意打乱传参顺序都可以正常运行 print(func11(a11=11, a10=10, a1=1, a3=3, a2=2, a5=5, a4=4, a7=7, a6=6, a9=9, a8=8)) # 输出结果 66,和预期一致
方案优势
- 完全兼容乱序关键字传参,参数匹配逻辑和手写逐行传参完全一致
- 保留了
func11的显式参数声明,IDE自动补全、类型检查、参数提示都能正常工作,不会丢失静态校验能力 - 提前缓存了被调函数的参数集合,没有重复解析的性能损耗
- 鲁棒性强:就算
func11内部在调用func10前定义了其他局部变量,也不会干扰参数筛选逻辑
其他可选方案(适用特定场景)
- 如果你确定代码运行在Python 3.7+(字典插入顺序作为语言特性保证),且
func11内在调用func10前不会定义其他局部变量,可以直接用位置参数切片的极简写法,缺点是鲁棒性差,不推荐生产环境使用:
def func11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11): # locals()按函数声明顺序返回参数,取前10个传给func10 return a11 + func10(*locals().values()[:10])
- 如果是临时写脚本不需要静态检查,也可以把外层函数改成接收
**kwargs,从参数字典里弹出多余参数后直接透传,缺点是丢失显式参数提示:
def func10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10): return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 def func11(**kwargs): a11 = kwargs.pop('a11') return a11 + func10(**kwargs)
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

