Python 3:print函数中的星号(*)是什么意思?

13

让我们来看一下:

print([object, ...], *, sep=' ', end='\n', file=sys.stdout)

我们如何解释那个'*'符号?通常星号('*')表示许多对象。但在这里,对我来说它是一个谜。夹在两个逗号之间......我甚至害怕认为这可能是一个打字错误。

http://docs.python.org/py3k/library/functions.html?highlight=print#print

2个回答

15

这是文档中的错误,是由于某人将新的Python 3功能应用到不应该使用它的地方而引起的。此后已经修复(请参见问题15831)。

文档中给出的函数签名以伪正式语法形式呈现,但只有在使用实际的Python语法时才有意义添加*标记。在这种情况下,签名中的部分 [object, ...], * 应列为 *objects

纠正后的版本如下:

print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False)

在线文档开发版本目前尚未更新,但文档源代码已经得到了纠正;我们会看看能否请求重新生成文档。

需要明确的是:在Python 3中,*语法是有效的,表示以下参数只能作为关键字参数使用,而不能作为位置参数。然而,这并不适用于 print() 函数,因为所有位置参数都将被打印出来,不可能被误解为关键字参数。


星号 * 仍然表示(除了将所有位置参数作为 objects 传递之外),以下参数应使用它们的名称提供,即我的答案是有效的。 - jfs
请问,Bug已经修复了吗?我给您提供了详细的链接,但是这个Bug仍然存在。至于命令行中的帮助,可以使用help(print)命令,它会输出:print(value, ..., sep=' ', end ='\n', file = sys.stdout)。所以,我不知道如何解释它。相对于“object”,“value”代表什么意思? - Kifsif
那么,两个逗号之间的“...”是什么意思呢?所以,我总觉得自己对这个函数理解不够透彻。 - Kifsif
@Kifsif:是的,在线文档仍需要重新生成。开发版本中仍包含不正确的文本。我向您提供了错误报告的链接,因为文档源已经更新,该报告已被标记为已修复。我从错误报告中获取了已更正的版本。两个逗号之间的“...”是错误生成的方法签名的一部分。 - Martijn Pieters

13

这意味着以下参数是仅关键字参数,即您不能将它们作为位置参数提供,必须使用它们的名称,如:

>>> def f(*, a): pass
... 
>>> f(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 0 positional arguments (1 given)
>>> f(a=1)
>>> # ok

另一个例子:

>>> def g(*a, b): pass
... 
>>> g(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: g() needs keyword-only argument b
>>> g(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: g() needs keyword-only argument b
>>> g(1, b=2)
>>> # ok
>>> g(1, 2, b=3)
>>> # ok

不,这意味着文档生成错误;, *是由文档工具的错误引起的。 - Martijn Pieters
@MartijnPieters: 尝试使用 def f(a, *, b): pass,并查看是否能够将 b 作为位置参数提供。 - jfs
4
Sebastian说得对,跟在*后面的参数只能被作为命名参数给出。这是Python3的一个新功能。 - Jochen Ritzel
1
@J.F.Sebastian:这也很酷,但不是 OP 所问的问题。 :-) - Martijn Pieters
@MartijnPieters:恰恰相反。你引用的那个错误是无关紧要的。在/之后的文档描述了相同的事情(除了3.3中的新flush参数):print()接受零个或多个位置参数进行打印,并且还有一些关键字参数,它们指定了打印选项及其默认值。 - jfs
@J.F.Sebastian:当然,但是 * 是一个干扰因素,语法也很令人困惑。使用实际的合法 Python 函数签名可以更清楚地说明函数接受的内容;[object, ...],* 语法是伪正式语法和文档中不必要的过度应用 * 标记的混合体。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接