我试图通过首先提供所有位置和非位置参数,然后再提供其余的非关键字参数来覆盖函数。
这里是执行步骤的功能:
def foo(a, b, c=3, *args, **kwargs):
print(f"Positional: a={a} | b={b} | c={c}")
print("*args", args)
print("**kwargs", kwargs)
from functools import partial
# a partial callable to supply *args later
part = partial(foo, a=2, b=4, c=3, extra=3)
# Here, I expect that the extra arguments would be called
# but instread raises TypeError
part('a', 'b', 'c')
但是出现了错误。
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-bf0b47424a01> in <module>()
11 # Here, I expect that the extra arguments would be called
12 # but instread raises TypeError
---> 13 part('a', 'b', 'c')
TypeError: foo() got multiple values for argument 'a'
是否有解决此问题的方法,而无需深入阅读它的可调用方的签名(例如使用inspect.signature
等)?
partial
的关键字参数与其包装的函数的命名参数不匹配;它只是保存它们以将其添加到partial
对象以后接收的参数中。也就是说,part(foo, a=2, b=4, c=3, extra=3)('a', 'b', 'c')
完全等于foo('a', 'b', 'c', a=2, b=4, c=3, extra=3)
。
您需要将位置参数传递给对partial
的调用。
part = partial(foo, 2, 4, 3, extra=3)
然后您将得到想要的结果:
>>> part('a', 'b', 'c')
Positional: a=2 | b=4 | c=3
*args ('a', 'b', 'c')
**kwargs {'extra': 3}