[英]Unpacking keyword arguments, but only the ones that match the function
Let's say I have a function: 假设我有一个功能:
def foo(a=None, b=None, c=None):
return "a:%s, b:%s, c:%s" % (a, b, c)
I have a dictionary with some (or none) of the arguments above, but also with keys that are not named arguments in the function, eg: 我有一个上面有一些(或没有)参数的字典,但也有一个在函数中没有命名参数的键,例如:
d = {'a': 1, 'x': 4, 'b': 2, 'y': 5}
If I call the following I will get an error, because 'x' and 'y' are not keyword arguments in the foo function. 如果我调用以下内容,我将收到错误,因为'x'和'y'不是foo函数中的关键字参数。
foo(**d) # error
Is there an elegant way of passing the arguments from a dictionary to a function, but only those values with keys that match the function arguments. 是否有一种优雅的方式将参数从字典传递给函数,但只有那些具有与函数参数匹配的键的值。
Please correct me if my argument/parameter terminology is off. 如果我的参数/参数术语关闭,请纠正我。
def foo(a = None, b=None, c=None,**extras):
return "a:%s, b:%s, c:%s" % (a, b, c)
here the **extras
will collect all the extra named/keyword arguments. 这里
**extras
将收集所有额外的命名/关键字参数。
@Ashwini Chaudhary has a very pythonic way of solving your problem. @Ashwini Chaudhary有一种非常pythonic的方式来解决你的问题。 However, it requires changing the signature of your
foo
function. 但是,它需要更改
foo
函数的签名。
If you don't want to change your function signature, you can use introspection to find out what arguments your function expects: 如果您不想更改函数签名,可以使用内省来查找函数所期望的参数:
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)
Interesting question. 有趣的问题。 I think that most people in real life use @Ashwini Chaudhary approach.
我认为现实生活中的大多数人都使用@Ashwini Chaudhary的方法。
I do agree with @Rodrigue that there are times you can't modify the call signature of the function (someone else's module perhaps) . 我同意@Rodrigue有时候你不能修改函数的调用签名(也许是其他人的模块) 。
When that happens, Use a function decorator 发生这种情况时, 请使用函数装饰器
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)
@wraps
from functools keeps the __name__
and __doc__
strings in tact. @wraps
从functools保持__name__
和__doc__
机智字符串。 You could also: 你也可以:
FunctionMaker
from the decorators module but this should be a more reusable approach. FunctionMaker
,但这应该是一种更可重用的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.