在给定条件的情况下,是否有一种巧妙的(pythonic?)方式在Python中使用命名参数默认值?

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)

——

(如果你想知道这个名字,我就用它来启动我的库用户会传递的回调函数。""可选"在这种情况下意味着func不必接受我调用的所有参数)


只是在这里闲逛…

1
do_something(**{ k: data[k] for k in ['Arg1', 'Arg2'] if k in data })

不过,这看起来很糟糕。