在下面的python代码场景中使用kwargs是否正确?

时间:2017-01-20 12:00:03

标签: python

在以下情况下使用kargs是否正确?

我有一个函数,在调用中需要五个参数,其中两个是可选的。所以,我可以删除它:

def f(p1, p2, p3, p4, p5, o1=None, o2=None)

def f(**kwargs)

因为我用params做这样的事情:

orig_path = "{0}/{1}/{3}/{4}".format(p1, p2, p3, p4)

orig_path = "{p1}/{p2}/{p3}/{p4}".format(kwargs)

我不知道哪种样式是Python在声明中使用的正确方式。有没有找到正确使用kwargs的指南?我在亚马逊上看过boto3 api通常使用kwargs构造但是......

1 个答案:

答案 0 :(得分:1)

根据经验,如果可以,您应该始终在函数定义中写出所有参数,并且理想情况下为它们提供描述性名称。

Zen of Python

  

明确比隐含更好。

以及

  

可读性计数。

使参数显式化有助于防止出现许多错误,例如调用参数太多或太少的函数或不存在的关键字参数。

它还有助于提高可读性,因为您可以轻松地从定义中找出函数所需的数量和参数,以及可能的关键字参数的默认值。有时,您甚至可以通过良好的参数名称猜测函数的功能,而无需查看文档。

有些IDE甚至可以在您打电话时自动查找定义,并在您输入时提醒您可能出现的问题。

这样做:

def twiddle_knobs(tuning, volume, panning=None, bass=6.0, midrange=-2.0, treble=1.5):
    """Modify the most important radio controls."""

    my_radio.modify_control(radio.TUNEFREQ, value=max(min(tuning, 120.0), 85.0))
    my_radio.modify_control(radio.VOL_MASTER, value=(volume / 100.0))

    if panning is not None:
        my_radio.modify_control(radio.VOL_LEFT, value=min(1.0 - panning / 100.0, 1.0))
        my_radio.modify_control(radio.VOL_RIGHT, value=min(1.0 + panning / 100.0, 1.0))

    for control, value in ((radio.EQU_BASS, bass),
                           (radio.EQU_MID,  midrange),
                           (radio.EQU_TREB, treble)):

        my_radio.modify_control(control, value=value, unit=radio.DB)

不要这样做:

def twiddle_knobs(*args, **kwargs):  # WARNING: never do this!
    my_radio.modify_control(radio.TUNEFREQ, max(min(args[0], 120.0), 85.0))
    my_radio.modify_control(radio.VOL_MASTER, args[1] / 100.0)

    if kwargs.get("panning") is not None:
        my_radio.modify_control(radio.VOL_LEFT, min(1.0 - kwargs["panning"] / 100.0, 1.0))
        my_radio.modify_control(radio.VOL_RIGHT, min(1.0 + kwargs["panning"] / 100.0, 1.0))

    for control, param, default in ((radio.EQU_BASS, "bass",      6.0),
                                    (radio.EQU_MID,  "midrange", -2.0),
                                    (radio.EQU_TREB, "treble",    1.5)):

        my_radio.modify_control(control, kwargs.get(param, default), radio.DB)

那么什么时候可以使用*args*kwargs

  • *args的一个用途是当您需要接收一系列内容时 是相似并提供相同的功能。但是,你也可以 只需使用普通参数并让调用者显式传入 名单。有时候,使用func([thing])调用函数看起来很像 但是很尴尬,尤其是大多数时候你只通过一个 事情或根本没有。这是*args的时间 改善这种情况。

  • 此外,当您需要传递某些位置和/或关键字时 你的函数接收的参数是你没有的另一个函数 控制,你不想指定你的参数 允许来电者通过,*args*kwargs - 在您的显式参数之后使用 - 是实现这一目标的方法。

  • 如果您有一组强烈要求的关键字参数 相关的功能,你不能完全预先定义什么的 关键字将,因为它们可能取决于某些内容 动态变化,这也是使用的一个很好的理由 *kwargs

此列表并非详尽无遗,但它应该为您提供一般性的想法。