如何忽略传递给函数的意外关键字参数?

rsp*_*cer 34 python dictionary function

假设我有一些功能, f

def f (a=None):
    print a
Run Code Online (Sandbox Code Playgroud)

现在,如果我有一本字典dct = {"a":"Foo"},我可以调用f(**dct)Foo打印结果.

但是,假设我有一本字典dct2 = {"a":"Foo", "b":"Bar"}.如果我打电话给f(**dct2)我一个

TypeError: f() got an unexpected keyword argument 'b'
Run Code Online (Sandbox Code Playgroud)

很公平.但是,无论如何,在f调用它的定义或调用它时,告诉python只是忽略任何不是参数名称的键?优选的是允许指定默认值的方法.

Abh*_*jit 27

作为@Bas发布的答案的扩展,我建议添加kwargs参数(变长关键字参数)作为函数的第二个参数

>>> def f (a=None, **kwargs):
    print a


>>> dct2 = {"a":"Foo", "b":"Bar"}
>>> f(**dct2)
Foo
Run Code Online (Sandbox Code Playgroud)

这必然足以满足要求

  1. __CODE__
  2. __CODE__

  • 但是如果该函数是由其他人(例如开源库)制作的,我就不能这样做 (8认同)
  • 我认为这就是OP正在寻找的。 (2认同)

Bas*_*els 13

这可以通过使用来完成**kwargs,它允许您收集dict中所有未定义的关键字参数:

def f(**kwargs):
    print kwargs['a']
Run Code Online (Sandbox Code Playgroud)

快速测试:

In [2]: f(a=13, b=55)
13
Run Code Online (Sandbox Code Playgroud)

编辑如果您仍想使用默认参数,则将原始参数保留为默认值,但您只需添加**kwargs以吸收所有其他参数:

In [3]: def f(a='default_a', **kwargs):
   ...:     print a
   ...:     

In [4]: f(b=44, a=12)
12
In [5]: f(c=33)
default_a
Run Code Online (Sandbox Code Playgroud)


Avi*_*dha 6

如果您无法将函数定义更改为使用未指定的** kwargs,则可以使用较旧版本的python中的argspec函数或Python 3.6中的签名检查方法来过滤由关键字参数传入的字典。

import inspect
def filter_dict(dict_to_filter, thing_with_kwargs):
    sig = inspect.signature(thing_with_kwargs)
    filter_keys = [param.name for param in sig.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD]
    filtered_dict = {filter_key:dict_to_filter[filter_key] for filter_key in filter_keys}
    return filtered_dict

def myfunc(x=0):
    print(x)
mydict = {'x':2, 'y':3}
filtered_dict = filter_dict(mydict, myfunc)
myfunc(**filtered_dict) # 2
myfunc(x=3) # 3
Run Code Online (Sandbox Code Playgroud)