如何从接收任意参数的函数返回functools.partial并避免参数重复错误
报错原因
你定义的f1第一个参数test属于位置/关键字混合参数,调用f2(2,3,a=4)时,第一个位置参数2会被优先分配给test,同时functools.partial已经绑定了test=42,导致同一个参数收到两个值,因此触发类型错误。
解决方案
方案1:调整参数顺序(最简单)
将f1的可变位置参数移到test之前,强制test只能通过关键字参数传递,避免和位置参数冲突:
import functools # 调整参数顺序,*a之后的test只能用关键字传参 f1 = lambda *a, test, **b: print(a, b, test) f2 = functools.partial(f1, test=42) f2(2,3,a=4)
运行输出:
(2, 3) {'a': 4} 42
方案2:自定义封装函数(更适配mock场景)
如果你需要同时存储调用参数、自定义返回值,直接封装wrapper比functools.partial更灵活,完全适配你的mock需求:
import functools def create_mock(target_func, pre_bind_kwargs, return_value=None): # 存储所有调用的入参,方便后续断言 call_records = [] @functools.wraps(target_func) def mock(*args, **kwargs): call_records.append({"args": args, "kwargs": kwargs}) if return_value is not None: return return_value # 先传入预绑定的关键字参数,再传入调用时的参数 return target_func(*args, **pre_bind_kwargs, **kwargs) # 把调用记录暴露给外部做断言 mock.call_records = call_records return mock # 无需修改原f1的定义 f1 = lambda test, *a, **b: print(a, b, test) f2 = create_mock(f1, pre_bind_kwargs={"test":42}) # 调用测试 f2(2,3,a=4) # 可查看调用记录做断言 print(f2.call_records)
运行输出:
(2, 3) {'a': 4} 42 [{'args': (2, 3), 'kwargs': {'a': 4}}]
内容的提问来源于stack exchange,提问作者jaaq
相关产品推荐
相关产品推荐

