仅将带有kwargs的关键字参数分配给尚未分配的参数

问题描述

我的问题很简单,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。请告诉我您的想法。