Форматирование строк в Python 3

114

Я делаю это в Python 2:

"(%d goals, $%d)" % (self.goals, self.penalties)

Что такое версия Python 3?

Я попытался найти примеры в Интернете, но продолжал получать версии Python 2.

JoseBazBaz
источник
Это не было устаревшим; ваш код работает нормально. Подробнее читайте здесь .
jackcogdill
32
Примечание для случайного читателя: знак доллара не имеет особого значения. Здесь просто знак доллара. (Спасибо Martijn Pieters)
kevinarpe
1
pyformat.info и python-course.eu/python3_formatted_output.php (не мои сайты)
Кристоф Русси
1
Знак доллара очень
сбивал с

Ответы:

173

Вот документы о синтаксисе «нового» формата. Примером может быть:

"({:d} goals, ${:d})".format(self.goals, self.penalties)

Если оба goalsи penaltiesявляются целыми числами (т. Е. Их формат по умолчанию в порядке), его можно сократить до:

"({} goals, ${})".format(self.goals, self.penalties)

И поскольку параметры являются полями self, есть также способ сделать это, используя один аргумент дважды (как отметил @Burhan Khalid в комментариях):

"({0.goals} goals, ${0.penalties})".format(self)

Разъяснение:

  • {} означает только следующий позиционный аргумент с форматом по умолчанию;
  • {0}означает аргумент с индексом в 0формате по умолчанию;
  • {:d} - следующий позиционный аргумент в десятичном целочисленном формате;
  • {0:d}- аргумент с индексом в 0десятичном целочисленном формате.

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

"({goals} goals, ${penalties})".format(goals=2, penalties=4)
"({goals} goals, ${penalties})".format(**self.__dict__)

"first goal: {0.goal_list[0]}".format(self)
"second goal: {.goal_list[1]}".format(self)

"conversion rate: {:.2f}".format(self.goals / self.shots) # '0.20'
"conversion rate: {:.2%}".format(self.goals / self.shots) # '20.45%'
"conversion rate: {:.0%}".format(self.goals / self.shots) # '20%'

"self: {!s}".format(self) # 'Player: Bob'
"self: {!r}".format(self) # '<__main__.Player instance at 0x00BF7260>'

"games: {:>3}".format(player1.games)  # 'games: 123'
"games: {:>3}".format(player2.games)  # 'games:   4'
"games: {:0>3}".format(player2.games) # 'games: 004'

Примечание. Как отмечали другие, новый формат не заменяет прежний, оба доступны как в Python 3, так и в более новых версиях Python 2. Кто-то может сказать, что это вопрос предпочтений, но ИМХО, новая версия намного более выразительна, чем старая, и должна использоваться при написании нового кода (если, конечно, он не ориентирован на более старые среды).

mgibsonbr
источник
9
Вы также можете сделать"({0.goals} goals, ${0.penalties})".format(self)
Бурхан Халид
Вам нужно вынести '%' вне фигурных скобок, например {: .2f%} -> {: .2f}%
SuperElectric
@SuperElectric вы имеете в виду, в этой строке: "conversion rate: {:.2%}".format(self.goals / self.shots)? У меня отлично работает и так ... (Python 3.4) Обратите внимание, что в нем нет f, я прошу форматировать в процентах, а не в виде числа с плавающей запятой.
mgibsonbr
Ты прав; похоже, он работает в Python 3.4, так что это нормально, так как OP спрашивал о Python3. Я только что обнаружил, что это не работает с python 2.7.6. "{:.2f}%".format(float_num)отлично работает для обоих.
SuperElectric
1
@JohnSchmitt Да, этот пример должен был дать тот же точный результат, что и код, указанный в вопросе. Здесь $нет особого значения ни в синтаксисе старого формата, ни в новом, поэтому он должен присутствовать в сгенерированной строке без изменений.
mgibsonbr
67

Python 3.6 теперь поддерживает интерполяцию сокращенных буквальных строк с помощью PEP 498 . В вашем случае новый синтаксис выглядит просто:

f"({self.goals} goals, ${self.penalties})"

Это похоже на предыдущий .formatстандарт, но позволяет легко делать такие вещи, как :

>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal('12.34567')
>>> f'result: {value:{width}.{precision}}'
'result:      12.35'
JDong
источник
12

Эта строка работает как есть в Python 3.

>>> sys.version
'3.2 (r32:88445, Oct 20 2012, 14:09:29) \n[GCC 4.5.2]'
>>> "(%d goals, $%d)" % (self.goals, self.penalties)
'(1 goals, $2)'
Марк Рид
источник
ХОРОШО. ПРОХЛАДНЫЙ. После того, как я разместил вопрос, я продолжил поиск и обнаружил, что мы должны сделать {% d} вместо простого% d, это тоже правильно? Или это единственный способ сделать это с помощью Python2?
JoseBazBaz
2
Python 3 вводит новый синтаксис - фигурные скобки - но вы не обязаны его использовать. Вы можете использовать как старый, так и новый. Но они разные; если вы используете фигурные скобки, вы не используете знаки процента.
Марк Рид,
2

Мне нравится такой подход

my_hash = {}
my_hash["goals"] = 3 #to show number
my_hash["penalties"] = "5" #to show string
print("I scored %(goals)d goals and took %(penalties)s penalties" % my_hash)

Обратите внимание на добавленные d и s в скобки соответственно.

вывод будет:

I scored 3 goals and took 5 penalties
fullstacklife
источник