Unpacking keyword arguments, but only the ones that match the function
假设我有一个函数:
1 2 | def foo(a=None, b=None, c=None): return"a:%s, b:%s, c:%s" % (a, b, c) |
我有一个字典,上面有一些(或没有)参数,但也有一些键不是函数中的命名参数,例如:
1 | d = {'a': 1, 'x': 4, 'b': 2, 'y': 5} |
如果调用下面的函数,我将得到一个错误,因为"x"和"y"不是foo函数中的关键字参数。
1 | foo(**d) # error |
是否有一种优雅的方式将参数从字典传递到函数,但只传递那些键与函数参数匹配的值?
如果我的参数/参数术语已关闭,请更正我的错误。
1 2 | def foo(a = None, b=None, c=None,**extras): return"a:%s, b:%s, c:%s" % (a, b, c) |
这里,
@Ashwini Chaudhary有一个很好的方法来解决你的问题。但是,它需要更改您的
如果不想更改函数签名,可以使用自省来了解函数期望的参数:
1 2 3 4 5 6 7 8 9 | arg_count = foo.func_code.co_argcount args = foo.func_code.co_varnames[:arg_count] args_dict = {} for k, v in d.iteritems(): if k in args: args_dict[k] = v foo(**args_dict) |
有趣的问题。我认为现实生活中的大多数人都使用@ashwini chaudhary的方法。
我同意@rodrigue的观点,有时您不能修改函数的调用签名(可能是其他人的模块)。
如果发生这种情况,请使用函数修饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from inspect import getargspec from funtools import wraps def allow_kwargs(foo): argspec = getargspec(foo) # if the original allows kwargs then do nothing if argspec.keywords: return foo @wraps(foo) def newfoo(*args, **kwargs): #print"newfoo called with args=%r kwargs=%r"%(args,kwargs) some_args = dict((k,kwargs[k]) for k in argspec.args if k in kwargs) return foo(*args, **some_args) return newfoo # with your function: @allow_kwargs def foo(a = None, b=None, c=None): return"a:%s, b:%s, c:%s" % (a,b,c) # with someone_elses function: from some_place import foo foo = allow_kwargs(foo) |
functools中的
- 从decorators模块中查看
FunctionMaker ,但这应该是一种更可重用的方法。 - 修改newfoo以允许额外的非关键字var不通过。