基于现有函数用lambda定义新函数:如何实现代码泛化?
泛化固定函数最后一个参数的实现
我有一段Python代码,基于已有函数定义了一个新函数,代码如下:
def myFunction(a: int, b: int, c: int): # Do stuff myNewFunction = lambda a, b: myFunction(a, b, 0)
这个新函数和原函数功能一致,但将最后一个参数固定为0。
我的问题是:若不知道原函数的参数个数,如何让上述实现更具泛化性?我自己写了一个意图正确但无效的示例:
def myFunction(a: int, b: int, c: int): # Do stuff func_args = myFunction.__code__.co_varnames func_args = func_args[:-1] myNewFunction = lambda *func_args : myFunction(*func_args, 0)
问题分析
你写的无效示例核心问题有两个:
__code__.co_varnames会包含函数内部的局部变量,不一定能准确获取到函数的参数列表;- lambda定义里的
*func_args是错误用法——func_args是参数名组成的元组,不能直接作为可变参数的标识符,这会触发语法错误。
泛化实现方案
方案一:简洁版(信任调用者传参)
直接用可变参数*args接收所有前置参数,调用原函数时拼接固定值作为最后一个参数:
def myFunction(a: int, b: int, c: int): print(a, b, c) # 泛化后的新函数 myNewFunction = lambda *args: myFunction(*args, 0) # 调用示例 myNewFunction(1, 2) # 输出:1 2 0
这个写法不管原函数有多少个位置参数,只要传入原函数参数总数减1个值,就能自动把最后一个参数固定为0。比如原函数有4个参数时,传入3个值即可调用。
方案二:严谨版(带参数个数校验)
如果需要严格限制传入的参数个数不超过原函数参数总数减1,可以用inspect模块获取函数签名来做校验:
import inspect def myFunction(a: int, b: int, c: int): print(a, b, c) def create_fixed_last_arg_func(original_func, fixed_value): # 获取原函数的参数列表 sig = inspect.signature(original_func) param_count = len(sig.parameters) if param_count == 0: # 处理原函数无参数的特殊情况 return lambda: original_func(fixed_value) def new_func(*args): if len(args) > param_count - 1: raise TypeError(f"最多允许传入{param_count - 1}个参数,实际传入了{len(args)}个") return original_func(*args, fixed_value) return new_func # 创建新函数 myNewFunction = create_fixed_last_arg_func(myFunction, 0) # 合法调用 myNewFunction(1, 2) # 输出:1 2 0 # 非法调用会报错:myNewFunction(1,2,3)
内容的提问来源于stack exchange,提问作者DJames
相关产品推荐
相关产品推荐

