Is there a neat (pythonic?) way to use named parameter defaults in Python given a condition?
本问题已经有最佳答案,请猛点这里访问。
我有一个带有一些命名参数的函数,以及一个包含具有这些名称的键以及其他键的字典。我想用字典中的值调用函数。
- 我不能使用
**data ,因为python会因为额外的键而提高TypeError: unexpected keyword argument 。 - dict可能不包含某些键,因此在不检查这些键是否存在的情况下,我无法引用它们(我不想从
get 传递默认值)。 - 我不能重写函数,因为它在一个单独的库中。
如何仅解包与功能参数匹配的键?
1 2 3 4 5 6 7 8 9 10 11 12 13 | def do_something(arg1=None, arg2=''): ... data = {'arg1': 1, 'arg2': 2, 'other': 3} # doesn't work if key doesn't exist do_something(arg1=data['arg1'], arg2=data['arg2']) # too verbose, hard to extend if 'arg1' in data: do_something(arg1=data['arg1'], arg2=data['arg2']) else: do_something(arg2=data['arg2']) |
或者,我只是从我的一个项目中挖出来的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def call_with_optional_arguments(func, **kwargs): ''' calls a function with the arguments **kwargs, but only those that the function defines. e.g. def fn(a, b): print a, b call_with_optional_arguments(fn, a=2, b=3, c=4) # because fn doesn't accept `c`, it is discarded ''' import inspect function_arg_names = inspect.getargspec(func).args for arg in kwargs.keys(): if arg not in function_arg_names: del kwargs[arg] func(**kwargs) |
在您的情况下,它可以使用如下:
1 | call_with_optional_arguments(do_something, **data) |
——
(如果你想知道这个名字,我就用它来启动我的库用户会传递的回调函数。""可选"在这种情况下意味着
只是在这里闲逛…
1 | do_something(**{ k: data[k] for k in ['Arg1', 'Arg2'] if k in data }) |
不过,这看起来很糟糕。