如何将dict的成员传递给函数

时间:2012-02-24 15:30:58

标签: python

假设我有一个我无法控制的功能,如下所示:

def some_func(foo, bar, bas, baz):
    do_something()
    return some_val

现在我想调用此函数从包含与此函数的参数相同的键的dict传递元素。我可以做类似的事情:

some_func(foo=mydict['foo'],
          bar=mydict['bar'],
          bas=mydict['bas'],
          baz=mydict['baz'])

我是否有一些优雅的方式可以利用密钥与parms相匹配的事实来减少冗长?我知道我可以通过整个字典,但是我要么说我要么不想或不能改变函数接受单个字典而不是单个参数。

谢谢, 杰里

2 个答案:

答案 0 :(得分:11)

这是**参数解包的用途:

some_func(**mydict)

另请参阅Python教程中的Unpacking argument lists

答案 1 :(得分:5)

正如Sven所说,您可以使用dict解包将**传递给函数。但是,如果dict包含不是目标函数的参数名称的键,则仅当您调用的函数使用**表示法接受关键字参数时,此方法才有效。如果没有,你会收到错误。

如果您正在调用的函数没有**kwargs参数,则处理它的最简单方法是添加一个。但如果你不能这样做,你有几种方法:

1)编写包装函数:

def wrapper(foo, bar, baz, quux, **kwargs):
    return some_func(foo, bar, baz, quux)

wrapper(**mydict)

2)编写一个函数来提取你需要的dict键:

def extract(dikt, keys):
    return dict((k, dikt[k]) for k in keys.split())

some_func(**extract(mydict, "foo bar baz quux"))

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)

请注意,这不允许您省略函数签名中具有默认值的参数。你可以做一些额外的内省来允许(func.func_defaults的长度决定哪个参数有默认值)。

这个内省适用于Python 2.x,Python 3及更高版本可能需要一些调整。出于这个原因,我更喜欢前两种方法中的一种。

PS - 感谢Sven在我的第二种方法中捕获了我失踪的**