首页 > 解决方案 > 仅将带有 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中有这样的机制吗?

标签: pythonkeyword-argument

解决方案


我以前从来没有写过装饰器,想知道我是否可以用一个来解决这个问题。我想我做到了!

我无法获得与您尝试使用完全相同的语法,因为装饰器可以拦截参数并对其进行处理,但它仍然存在在输入过程中将参数名称加倍的问题。因此解决方案涉及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, b, c)

foo(a=5, b=33, defs=params)

结果:

5 33 15

我意识到这里还有很多工作要做,以支持位置参数和传递*argsand **kwargs。请告诉我你的想法。


推荐阅读