Форматирование строк или "Что означает %s в python?"

Форматирование строк или "Что означает %s в python?"
  • Опубликовано:
  • Теги: python
Недавно узнал, что блог время от времени находят по запросу "что означает %s в python". Вспоминаю себя – когда я начинал изучать Python, мне хотелось быстрых и понятных ответов (мол, "не морочь голову, пальцем покажи"). Для таких нетерпеливых эта статья.

Оглавление
  1. Примеры
  2. Как работает оператор '%'
  3. Как работает встроенная функция format()

Для начала несколько примеров

Форматирование строк:
>>> name = 'Vasya'
>>> print "My name is %s" % (name)
My name is Vasya
С указанием размера полей (перед 'Vasya' стоит пять пробелов, т.е. всего десять символов):
>>> print "My name is %10s. That's my name." % (name)
My name is      Vasya. That's my name.
То же самое, но выровненное по левому краю:
>>> print "My name is %-10s. That's my name." % (name)
My name is Vasya     . That's my name.
Когда это может быть полезно:
>>> drinks = {'Long Island': 3, 'Bloody Mary': 2, 'Margarita':4}
>>> print "%-15s%-5s" % ("Name", "Qty")
Name           Qty
>>> for k,v in drinks.items():
...     print "%-15s%-3s" % (k, v)
...
Bloody Mary     2
Long Island     3
Margarita       4
Если понадобится вывести целую часть числа:
>>> num = 12.34
>>> print "%d" % (num)
12
Вперемешку:
>>> age = 25
>>> print "My name is %s. I'm %d." % (name, age)
My name is Vasya. I'm 25.

Теперь вкратце как работает оператор %

Выражение форматирования можно условно разделить на три части:

определение_формата + % + объект(ы)

Обозначения %s, %d, %g и т. п. - это форматы типов данных. Если вы знакомы с языком Си, то это тот же синтаксис, что используется для вывода на печать printf().

Спецификации различных типов данных Python приведены в следующей таблице:

Формат Значение
'd' Целое десятичное число.
'i' Целое десятичное число.
'o' Восьмеричное число.
'u' Устаревший тип – то же что 'd'.
'x' Шестнадцатеричное число (нижний регистр).
'X' Шестнадцатеричное число (верхний регистр).
'e' Вещественное число в экспоненциальном виде (нижний регистр).
'E' Вещественное число в экспоненциальном виде (верхний регистр).
'f' Вещественное число в десятичном виде.
'F' Вещественное число в десятичном виде.
'g' Вещественное число. Использует формат 'f' или 'e' в нижнем регистре.
'G' Вещественное число. Использует формат 'F' или 'E' в верхнем регистре.
'c' Один символ (или цифра).
'r' Строка, в которую любой объект Python конвертируется с помощью repr().
's' Строка, в которую любой объект Python конвертируется с помощью str().
'%' Аргумент не конвертируется, выводится просто символ '%'.

Встроенная функция format()

Работает так:
str.format()

В строке "поля для замены" заключаются в фигурные скобки {}. Все, что не заключено в скобки, воспринимается как обычный текст, которые копируется в неизменном виде. Чтобы передать в тексте символы фигурных скобок, их дублируют: {{ и }}.
Поля для замены форматируются следующим образом:

поле_для_замены    ::=  "{" [имя_поля] ["!" конверсия] [":" спецификация] "}"
имя_поля           ::=  имя_аргумента ("." имя_атрибута | "[" номер_элемента "]")*
имя_аргумента      ::=  [идентификатор | integer]
имя_атрибута       ::=  идентификатор
индекс_элемента    ::=  integer | строковый индекс
строковый_индекс   ::=  <любой символ кроме "]"> +
конверсия          ::=  "r" | "s" # str или repr
спецификация       ::=  <описано ниже>
где
спецификация  ::= [[заглушка]выравнивание][знак][#][0][ширина][,][.точность][тип]
заглушка      ::= <любой символ>
выравнивание  ::= "<" | ">" | "=" | "^"
знак          ::=  "+" | "-" | " "
ширина        ::=  integer # ширина поля
точность      ::=  integer # знаки после десятичной запятой
тип           ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
Записывается так:
>>> print """\n{0}
... Сидел на стене
... {0}
... Свалился во сне.""".format('Шалтай-Болтай')

Шалтай-Болтай
Сидел на стене
Шалтай-Болтай
Свалился во сне.

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

Еще пример форматирования:

>>> toc = (
... ('Первая глава', '3'),
... ('Вторая глава', '150')
... )
>>> for line in toc:
...   print('{:.<30}{}'.format(*line))
...
Первая глава.......3
Вторая глава.......150

Возможно, вам будет интересно