这个问题可能会比较长,所以我提前道歉。
在Python中,我们可以在以下三种情况下使用 * :
I. 当定义一个带有任意数量参数的可调用函数时,我们可以使用 * ,例如在这个例子中:
def write_multiple_items(file, separator, *args):
file.write(separator.join(args))
在这种情况下,多余的位置参数将被收集到一个元组中。
II. 反过来的情况是,当参数已经以列表或元组的形式存在,并且我们希望将它们拆包为函数调用需要的单独位置参数,例如在这个例子中:
>>> 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开始,*也用于扩展列表或元组拆包的上下文中,例如对于元组在这个例子中:
>>> a, *b, c = range(5)
>>> b
[1, 2, 3]
或者用于列表:
>>> [a, *b, c] = range(5)
>>> b
[1, 2, 3]
在这两种情况下,未分配给任何必需表达式的可迭代项都会分配给一个列表。所以问题来了:在情况I中,额外的参数被收集到一个元组中,而在情况III中,额外的项被分配到一个列表中。为什么会有这种差异?我能找到的唯一解释是PEP 3132中提到的:“可能讨论的更改包括:将星号目标更改为元组而不是列表。这将与函数的*args保持一致,但会使结果的进一步处理更加困难。”然而,从教育的角度来看,这种不一致性是有问题的,特别是考虑到如果您想要处理结果,您可以始终说list(b)(假设上面的示例中b是一个元组)。我是否遗漏了什么?