Подтвердить что ты не робот

Новый стиль форматирования с кортежем как аргумент

Почему я не могу использовать tuple в качестве аргумента для форматирования в новом стиле ( "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.
4b9b3361

Ответ 1

В старом способе форматирования использовался двоичный оператор %. По своей природе он может принимать только два аргумента. Новый способ форматирования использует метод. Методы могут принимать любое количество аргументов.

Так как вам иногда нужно передавать несколько вещей для форматирования, и несколько неудобно создавать кортежи с одним элементом все время, в стиле старого стиля появился хак: если вы передадите его как кортеж, он будет использовать содержимое кортежа как вещи для форматирования. Если вы передадите ему нечто, отличное от кортежа, оно будет использовать это как единственное, что нужно форматировать.

Новый способ не нуждается в таком взломе: поскольку это метод, он может принимать любое количество аргументов. Таким образом, несколько вещей для форматирования должны передаваться как отдельные аргументы. К счастью, вы можете распаковать кортеж в аргументы, используя *:

print("First item: {:d}, second item: {:d} and third item: {:d}.".format(*tuple))

Ответ 2

Как 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 - не используйте встроенные имена для переменных, так как вы их перезапишете, и это может вызвать проблемы с дорожкой.

Ответ 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.

Я считаю это менее понятным, чем подход *.