如何选择在Python中传递带有非默认值的参数?

时间:2016-10-05 15:15:12

标签: python syntactic-sugar

我有以下方法:

def a(b='default_b', c='default_c', d='default_d'):
    # …
    pass

我有一些命令行界面,允许提供变量user_buser_cuser_d或将它们设置为None - 即简单的Python { {1}}模块。

我想拨打电话:

argparse

如果变量是a(b=user_b if user_b is not None, c=user_c if user_c is not None, d=user_d if user_d is not None) ,我想使用方法参数中的默认值。

我找到的唯一方法是检查用户变量的所有组合:

None

什么是更有效,更奇特和Pythonic的方法来解决我的问题?

4 个答案:

答案 0 :(得分:3)

arg_dict = {}
if user_b is not None:
    arg_dict["b"] = user_b
if user_c is not None:
    arg_dict["c"] = user_c
if user_d is not None:
    arg_dict["d"] = user_d

a(**arg_dict)

虽然不是很漂亮。

更好的方法就是重新编写函数a以接受None作为默认答案,然后检查一下。 (即if b is None: b = "default_b"

答案 1 :(得分:1)

您可以编写一个过滤掉不需要的值的函数,然后使用它来清除目标函数调用。

def scrub_params(**kw):
    return {k:v for k,v in kw.items() if v is not None}

some_function(**scrub_params(foo=args.foo, bar=args.bar))

答案 2 :(得分:1)

这里有tdelaney's answer(启动我的+1)的轻微变化,装饰 a使用另一个删除所有关键字参数的函数传递给值为None的decoratee。

from functools import wraps


# You can reuse this decorator for all functions that might be
# invoked in your CLI that should handle their arguments like
# 'a' does.
def scrub_parameters(f):
    @wraps(f)
    def wrapper(**kwargs):
        kwargs = {k: v for k, v in kwargs.items() if v is not None}
        return f(**kwargs)

    return wrapper


@scrub_parameters
def a(b='default_b', c='default_c', d='default_d'):
    print('b={}, c={}, d={}'.format(b, c, d))


if __name__ == '__main__':
    arg_dict = {'b': 'user_b', 'c': 'user_c', 'd': None}
    a(**arg_dict)  # b=user_b, c=user_c, d=default_d

    arg_dict = {'b': None, 'c': 'user_c', 'd': None}
    a(**arg_dict)  # b=default_b, c=user_c, d=default_d

答案 3 :(得分:0)

您可以使用数据定义一个类,并将该对象作为参数传递。

class Args:
    def __init__(self, user_b, user_c, user_d):
        self.b = user_b
        self.c = user_c
        self.d = user_d