关于何时在API中使用varargs函数签名而不是将迭代函数传递给函数,是否有一个很好的经验法则? (“varargs”是“变量”或“可变数量的参数”的缩写;即*args
)
例如,os.path.join
有一个vararg签名:
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
答案 0 :(得分:8)
当您希望用户将参数列表指定为呼叫站点处的代码或具有单个值是常见情况时,请考虑使用varargs。当您希望用户从其他地方获取参数时,请不要使用varargs。如有疑问,请不要使用varargs。
使用您的示例, os.path.join 最常见的用例是使用路径前缀并在其上附加文件名/相对路径,因此调用通常看起来像 os .path.join(prefix,some_file)。另一方面, any()通常用于处理数据列表,当您知道所有不使用的元素 any([a,b,c])< / em>,您使用 a或b或c 。
答案 1 :(得分: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')
这样的东西看起来有点不对(因为复数),但我更喜欢它而不是其他选择。
答案 2 :(得分:0)
当参数列表可变时,您应该使用它。
是的,我知道答案有点愚蠢,但这是真的。也许你的问题有点弥漫。 : - )
如果您想要不同的行为(如上面的min())或者您只是不想强制调用者发送所有参数,则默认参数(如上面的min())会更有用。
* arg用于具有相同类型的参数的变量列表。加入是一个典型的例子。您可以将其替换为带有列表的参数。
** kw适用于您有许多不同类型的参数,其中每个参数也连接到一个名称。一个典型的例子是当你想要一个通用函数来处理表单提交或类似的时候。
答案 3 :(得分: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
适用于一组字符串。<登记/>
因此,在第一种情况下,您请求一个列表;在第二个中,你直接请求字符串。
换句话说,界面的表现力应该是选择参数传递方式的主要指南。