问题描述
我的问题很简单,python中有没有办法
params = {'b': 10,'c': 15}
def foo(a,b,c,**kwargs):
pass
foo(a=5,b=10,**params)
我希望此代码仅将c分配给15,但它会引发
TypeError:foo()为关键字参数'b'获得了多个值
在python中有这样的机制吗?
解决方法
我以前从未写过装饰器,想知道我是否可以用一个装饰器解决这个问题。我想我做到了!
我无法获得与尝试使用的语法完全相同的语法,因为装饰器可以截取参数并对其进行处理,但是仍然存在将参数名称加倍的问题。因此,解决方案涉及到我编写的merge_defs
装饰器(该装饰器将进入我假设的模块),并对语法进行了少许更改:
import inspect
def merge_defs(func):
def wrapper(*args,**kwargs):
_kwargs = {}
defs = kwargs.pop('defs')
for pname,p in inspect.signature(func).parameters.items():
if pname in kwargs:
_kwargs[pname] = kwargs[pname]
elif pname in defs:
_kwargs[pname] = defs[pname]
return func(**_kwargs)
return wrapper
params = {'b': 10,'c': 15}
@merge_defs
def foo(a,b,c):
print(a,c)
foo(a=5,b=33,defs=params)
结果:
5 33 15
我意识到这里仍然需要做的工作,以支持位置参数并传递*args
和**kwargs
。请告诉我您的想法。