如何在Python中动态固定函数参数?
解决方案:动态固定函数参数的Pythonic实现
问题背景
现有一个多参数函数:
def my_fun(x, a, b, c, d, e, f, g): return x, a, b, c, d, e, f, g
需要实现一个高阶函数fixing_function,传入固定参数的字典(如{"a": 100, "e": 200})后,返回一个新函数。新函数仅接受未被固定的参数作为位置参数,内部调用原函数时自动填入固定值,示例返回函数如下:
def fixed_function(x, b, c, d, f, g): return x, 100, b, c, d, 200, f, g
要求避免使用exec,采用更符合Python风格的实现,且适配scipy.optimize.curve_fit()的使用场景(无法在原函数中使用*args/**kwargs)。
实现代码
import inspect from functools import wraps def my_fun(x, a, b, c, d, e, f, g): return x, a, b, c, d, e, f, g def fixing_function(fixed_params): # 获取原函数的参数签名与参数列表 sig = inspect.signature(my_fun) param_names = list(sig.parameters.keys()) # 筛选出未被固定的参数,保留原顺序 free_param_names = [name for name in param_names if name not in fixed_params] @wraps(my_fun) def fixed_function(*args): # 将传入的位置参数映射到未固定参数 free_param_map = dict(zip(free_param_names, args)) # 合并固定参数与传入参数 all_params = {**fixed_params, **free_param_map} # 按原函数参数顺序传递所有参数 return my_fun(*(all_params[name] for name in param_names)) # 更新新函数的签名,使其显示正确的参数列表 fixed_function.__signature__ = sig.replace( parameters=[sig.parameters[name] for name in free_param_names] ) return fixed_function
使用示例
# 生成固定a=100、e=200的函数 fixed_func = fixing_function({"a": 100, "e": 200}) # 调用测试:传入x和未固定的b,c,d,f,g参数 print(fixed_func(1, 2, 3, 4, 5, 6)) # 输出: (1, 100, 2, 3, 4, 200, 5, 6)
方案说明
- 参数顺序保障:通过
inspect.signature获取原函数的参数顺序,确保新函数的参数顺序与原函数中未固定参数的顺序一致,适配curve_fit对参数位置的要求。 - 闭包封装:利用闭包保存固定参数,避免全局变量污染,同时保证新函数的调用逻辑简洁。
- 签名修正:修改新函数的
__signature__属性,让help()或IDE能正确识别参数列表,提升开发体验。
内容的提问来源于stack exchange,提问作者Heisenbugs
相关产品推荐
相关产品推荐

