31

为什么我不能使用元组作为新样式(“string”.format())的格式化程序的参数?它在旧样式(“字符串”%)中工作正常吗?

此代码有效:

>>> tuple = (500000, 500, 5)
... print "First item: %d, second item: %d and third item: %d." % tuple

    First item: 500000, second item: 500 and third item: 5.

这不会:

>>> tuple = (500000, 500, 5)
... print("First item: {:d}, second item: {:d} and third item: {:d}."
...       .format(tuple))

    Traceback (most recent call last):
     File "<stdin>", line 2, in <module>
    ValueError: Unknown format code 'd' for object of type 'str'

即使使用 {!r}

>>> tuple = (500000, 500, 5)
... print("First item: {!r}, second item: {!r} and third item: {!r}."
...       .format(tuple))

    Traceback (most recent call last):
     File "<stdin>", line 2, in <module>
    IndexError: tuple index out of range

虽然它以这种方式工作:

>>> print("First item: {!r}, second item: {!r} and third item: {!r}."
...       .format(500000, 500, 50))

    First item: 500000, second item: 500 and third item: 5.
4

3 回答 3

51

旧的格式化方式使用二元运算符,%. 就其性质而言,它只能接受两个参数。新的格式化方式使用一种方法。方法可以采用任意数量的参数。

因为你有时需要传递多个东西来格式化,并且总是用一个项目创建元组有点笨拙,所以旧式的方法想出了一个技巧:如果你将它作为一个元组传递,它将使用tuple 作为要格式化的东西。如果您传递元组以外的其他内容,它将使用它作为唯一格式化的东西。

新方法不需要这样的技巧:因为它是一种方法,它可以接受任意数量的参数。因此,需要将多个要格式化的东西作为单独的参数传递。幸运的是,您可以使用以下方法将元组解包到参数中*

print("First item: {:d}, second item: {:d} and third item: {:d}.".format(*tuple))
于 2013-03-03T02:55:03.937 回答
18

正如icktoofay解释的那样,在旧的格式化风格中,如果你传入一个元组,Python 会自动解包它。

但是,您不能在该str.format方法中使用元组,因为 Python 认为您只传递了一个参数。您必须使用*运算符解压缩元组,才能将每个元素作为单独的参数传递。

>>> t = (500000, 500, 5)
>>> "First item: {:d}, second item: {:d} and third item: {:d}.".format(*t)
First item: 500000, second item: 500 and third item: 5.

此外,您会注意到我将您的tuple变量重命名为t- 不要为变量使用内置名称,因为您将覆盖它们,这可能会导致问题出现。

于 2013-03-03T02:55:31.883 回答
3

format()如果您手动索引花括号内的元组,实际上可以使用元组作为参数:

>>> t = (500000, 500, 5)
>>> print("First item: {0[0]:d}, second item: {0[1]:d} and third item: {0[2]:d}.".format(t))
First item: 500000, second item: 500 and third item: 5.

不过,我发现这比*方法不太清楚。

于 2017-02-12T06:53:29.507 回答