Python:向方法调用添加可选参数的更优雅的方式

Python: More elegant way to add optional parameters to method call

这可能看起来微不足道,但这是我 运行 经常遇到的情况,并且希望找到一种更优雅的方式来编写此代码。该方法虽然与问题不太相关,但采用文本值和可选的 is_checked 值来创建单选按钮(使用 dominate)。在这种情况下,我无法将 'checked' 设置为 None 或 false - 它必须存在或不存在。不过,我似乎不必将 'input' 行写两次,只是为了有选择地添加一个参数。

def _get_radio_button(text: str, is_checked=False):

    with label(text, cls="radio-inline") as lbl:
        if is_checked:
            input(text, type="radio", name="optradio", checked='checked')
        else:
            input(text, type="radio", name="optradio")

    return lbl

这将是我的第二种方法,但它是相同的代码行并且可读性较差 - 尽管可能有点干。

a = dict(type='radio', name='optradio')
if is_checked: 
    a['checked']='checked'
with label(text, cls="radio-inline") as lbl:
    input(text, **a)

问题:如何在不牺牲可读性的情况下用尽可能少的行来处理这个代码案例?

您的代码看起来不错,除了 a 的命名明显不同,它可能是 input_opts 或类似的东西。

另一种让它更清晰的可能性是对常见的东西使用直接关键字参数,并使用 ** 注入可选的参数。当只有一个是可选的时,这可以很短,例如:

checked_arg = {'checked': 'checked'} if is_checked else {}
with label(text, cls="radio-inline") as lbl:
    input(text, type="radio", name="optradio", **checked_arg)

仅作为概念:)您可以用这种方式装饰自己的或外来的(库)函数。更重要的是,您可以将装饰器设置为 class(使用 __call__ 方法装饰底层函数),可以使用简单的 "morphisms" 底层函数参数(它们可能是函数列表 -作为装饰器 class 构造函数的参数)。你也可以制作更多声明式风格的装饰器并检查底层函数参数(例如默认值)——你只受限于自己的幻想:)所以:

from functools import wraps

def adapt_gui_args(callable):
    @wraps(callable)
    def w(*args, **kwargs):
        if kwargs.pop('is_checked', False): kwargs['checked'] = 'checked'
        return callable(*args, **kwargs)
    return w

# may be decorated with adapt_gui_args if it's your function
def input(*args, **kwargs):
    print("args: ", args)
    print("kwargs: ", kwargs)

# decorate input function outside its source body
input = adapt_gui_args(input)

def test(is_checked=False):
    input(1, 2, type="radio", is_checked=is_checked)

test(False)
test(True)