7

关于何时应该更喜欢 API 中的 varargs 函数签名而不是将可迭代对象传递给函数,是否有一个好的经验法则?(“varargs”是“variadic”或“variable-number-of-arguments”的缩写;即*args

例如,os.path.join具有可变参数签名:

os.path.join(first_component, *rest) -> str

min允许:

min(iterable[, key=func]) -> val
min(a, b, c, ...[, key=func]) -> val

any/all只允许一个可迭代的:

any(iterable) -> bool
4

4 回答 4

8

当您希望用户将参数列表指定为调用站点的代码或具有单个值是常见情况时,请考虑使用可变参数。当您希望您的用户从其他地方获取参数时,请不要使用可变参数。如有疑问,请不要使用可变参数。

使用您的示例, os.path.join最常见的用例是具有路径前缀并在其上附加文件名/相对路径,因此调用通常看起来像os.path.join(prefix, some_file)。另一方面,any()通常用于处理数据列表,当您知道所有不使用的元素时any([a,b,c]),您使用a 或 b 或 c

于 2009-07-16T10:48:23.427 回答
4

我的经验法则是在您可能经常在传递一个和多个参数之间切换时使用它。而不是有两个功能(例如一些 GUI 代码):

def enable_tab(tab_name)
def enable_tabs(tabs_list)

甚至更糟,只有一个功能

def enable_tabs(tabs_list)

并将其用作enable_tabls(['tab1']),我倾向于仅使用:def enable_tabs(*tabs)。虽然,看到类似的东西enable_tabs('tab1')看起来有点错误(因为复数),但我更喜欢它而不是替代品。

于 2009-07-16T10:37:13.107 回答
0

当您的参数列表是可变的时,您应该使用它。

是的,我知道答案有点愚蠢,但这是真的。也许你的问题有点分散。:-)

当您想要不同的行为(如上面的 min() )或不想强制调用者发送所有参数时,默认参数(如上面的 min() )更有用。

*arg 用于当您具有相同类型的参数的变量列表时。加盟就是一个典型的例子。您也可以将其替换为带有列表的参数。

**kw 用于当您有许多不同类型的参数时,其中每个参数也连接到一个名称。一个典型的例子是当你想要一个通用函数来处理表单提交或类似的。

于 2009-07-16T10:46:28.517 回答
0

它们是完全不同的接口。
在一种情况下,您有一个参数,在另一种情况下,您有很多参数。

any(1, 2, 3)
TypeError: any() takes exactly one argument (3 given)

os.path.join("1", "2", "3")
'1\\2\\3'

这实际上取决于要强调的内容:any适用于列表(嗯,有点),同时os.path.join适用于一组字符串。
因此,在第一种情况下,您需要一份清单;第二,您直接请求字符串。

换句话说,接口的表现力应该是选择参数传递方式的主要准则。

于 2009-07-16T10:48:48.107 回答