【发布时间】:2011-03-13 02:57:00
【问题描述】:
这个问题会比较长,所以我先道歉。
在 Python 中,我们可以在以下三种情况下使用 *:
I.在定义一个我们希望可以使用任意数量的参数调用的函数时,例如in this example:
def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
在这种情况下,多余的位置参数被收集到一个元组中。
II. 相反的情况是,当参数已经在 list 或 tuple 中时,我们希望将它们解包以便需要单独位置参数的函数调用,例如in this example:
>>> range(3, 6) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]
III. 从 Python 3 开始,* 也用于扩展 list 或 tuple 解包的上下文中,例如 in this example对于元组:
>>> a, *b, c = range(5)
>>> b
[1, 2, 3]
或者对于列表:
>>> [a, *b, c] = range(5)
>>> b
[1, 2, 3]
在这两种情况下,被解包的可迭代对象中所有未分配给任何强制表达式的项都将分配给一个列表。
所以问题来了:如果 I 额外的参数被收集到一个 tuple 中,而如果 III 额外的项目被分配列表。这种差异从何而来?我能找到的唯一解释是在 PEP 3132 中说:
讨论的可能变化是:
[...]
使加星标的目标成为元组而不是列表。这将是 与函数的 *args 一致, 但进一步处理 结果更难。
然而,从教学的角度来看,这种缺乏一致性是有问题的,特别是考虑到如果你想处理结果,你总是可以说 list(b) (假设上面的例子中的 b 是一个元组)。我错过了什么吗?
【问题讨论】: