假设我有一个我无法控制的功能,如下所示:
def some_func(foo, bar, bas, baz):
do_something()
return some_val
Run Code Online (Sandbox Code Playgroud)
现在我想调用此函数从包含与此函数的参数相同的键的dict传递元素.我可以这样做:
some_func(foo=mydict['foo'],
bar=mydict['bar'],
bas=mydict['bas'],
baz=mydict['baz'])
Run Code Online (Sandbox Code Playgroud)
是否有一些优雅的方式,我可以利用这个事实,密钥匹配parms这样做不那么冗长?我知道我可以通过整个字典,但是我要么说我要么不想或不能改变函数接受单个字典而不是单个参数.
谢谢,杰里
Sve*_*ach 11
这就是**拆包的论点:
some_func(**mydict)
Run Code Online (Sandbox Code Playgroud)
另请参阅Python教程中的解压缩参数列表.
正如Sven所说,你可以dict使用**解包将一个函数传递给函数.但是,如果dict包含的键不是目标函数的参数名,则仅当您调用的函数使用**表示法接受关键字参数时,此方法才有效.如果没有,您将收到错误.
如果您正在调用的函数没有**kwargs参数,则处理它的最简单方法是添加一个参数.但如果你不能这样做,你有几种方法:
1)编写包装函数:
def wrapper(foo, bar, baz, quux, **kwargs):
return some_func(foo, bar, baz, quux)
wrapper(**mydict)
Run Code Online (Sandbox Code Playgroud)
2)编写一个函数来提取你需要的dict键:
def extract(dikt, keys):
return dict((k, dikt[k]) for k in keys.split())
some_func(**extract(mydict, "foo bar baz quux"))
Run Code Online (Sandbox Code Playgroud)
3)编写一个功能,对你正在调用的函数进行内省,并从字典中提取你需要的键 - 基本上与#2相同,除非你不必"重复自己".
def call_with_dict(func, dikt):
func(**dict((k, dikt[k]) for k in
func.func_code.co_varnames[:func.func_code.co_argcount]))
call_with_dict(some_func, my_dict)
Run Code Online (Sandbox Code Playgroud)
请注意,这不允许您省略在函数签名中具有默认值的参数.您可以进行一些额外的内省以允许(func.func_defaults确定哪个参数具有默认值的长度).
这个内省适用于Python 2.x,Python 3及更高版本可能需要一些调整.出于这个原因,我更喜欢前两种方法中的一种.
PS - 感谢Sven **在我的第二种方法中抓住了我的失踪.