Сообщить об ошибке.

Класс Formatter() модуля string

Настройка собственных строк форматирования

Класс Formatter в модуле string позволяет создавать и настраивать собственное поведение форматирования строк, используя ту же реализацию, что и встроенный метод str.format().

import string

s = string.Formatter()

Класс Formatter() имеет следующие публичные методы:

s.format(format_string , / , *args , **kwargs):

Метод s.format() представляет собой основной метод API. Он принимает строку формата format_string и произвольный набор позиционных *args и ключевых **kwargs аргументов. Это просто оболочка, которая вызывает s.vformat().

s.vformat(format_string, args, kwargs):

Метод s.vformat() выполняет фактическую работу по форматированию. Он предоставляется в виде отдельной функции для случаев, когда требуется передать заранее определенный словарь аргументов, а не распаковывать и переупаковывать словарь как отдельные аргументы с использованием синтаксиса *args и **kwargs. Метод s.vformat() выполняет работу по разбиению строки формата на символьные данные и поля замены. Он вызывает различные методы, описанные ниже.


Класс Formatter() определяет ряд методов, которые должны быть заменены подклассами:

s.parse(format_string):

Метод s.parse() производит цикл над format_string и возвращает итерацию кортежей (literal_text, field_name, format_spec, conversion). Метод s.parse() используется методом s.format() для разбиения строки на литеральный текст или поля замены.

Значения в кортеже концептуально представляют собой отрезок буквального текста, за которым следует одно поле замены. Если нет литерального текста, если два поля замены расположены друг за другом, то literal_text будет строкой нулевой длины. Если заменяющего поля нет, то значения field_name, format_spec и conversion будут иметь значения None.

s.get_field(field_name, args, kwargs):

Метод s.get_field(), учитывая field_name, возвращаемое s.parse(), преобразует его в форматируемый объект. Возвращает кортеж типа (obj, used_key). Версия по умолчанию принимает строки формы, такие как 0[name] или label.title. Аргументы args и kwargs передаются в метод s.vformat(). Возвращаемое значение used_key имеет то же значение, что и ключевой параметр s.get_value().

s.get_value(key, args, kwargs):

Метод s.get_value() извлекает заданное значение поля. Ключевым аргументом будет либо целое число, либо строка. Если это целое число, то оно представляет индекс позиционного аргумента в args, если это строка, то оно представляет именованный аргумент в kwargs.

Параметр args задает список позиционных аргументов для s.format(), а параметр kwargs - словарь аргументов ключевых слов.

Для составных имен полей этот метод вызываются только для первого компонента имени Поля. Последующие компоненты обрабатываются с помощью обычных атрибутов и операций индексирования.

Так, например, выражение поля 0.name вызовет метод s.get_value() с ключевым аргументом 0. Атрибут name будет найден после того, как s.get_value() возвратится, вызвав встроенную функцию s.getattr().

Если индекс или ключевое слово относится к элементу, который не существует, то вызывается исключение IndexError или KeyError.

s.check_unused_args(used_args, args, kwargs):

Метод s.check_unused_args() реализует проверку неиспользуемых аргументов, если это необходимо. Аргументами этой функции является набор всех ключей аргументов used_args, которые фактически были указаны в строке формата (целые числа для позиционных аргументов и строки для именованных аргументов), а также ссылка на args и kwargs, которые были переданы в метод s.vformat(). Набор неиспользованных аргументов можно рассчитать по этим параметрам. Метод s.check_unused_args() вызывает исключение, если проверка не пройдена.

s.format_field(value, format_spec):

Метод s.format_field() просто вызывает глобальный встроенный format(). Метод предоставляется для того, чтобы подклассы могли переопределять его.

s.convert_field(value, conversion):

Метод s.convert_field() преобразует значение возвращаемое методом s.get_field() для данного типа преобразования, как в кортеже возвращаемом s.parse() методом. Версия по умолчанию понимает типы преобразования 's' - str, 'r' - repr и 'a' - ascii.


Синтаксис строки формата.

Строковой метод str.format() и класс Formatter разделяют один и тот же синтаксис для строк формата, хотя в случае Formatter, подклассы могут определить свой собственный формат синтаксис строки. Синтаксис связан с синтаксисом форматированных строковых литералов , но есть различия.

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

Грамматика для поля замены {} выглядит следующим образом:

"{" [ field_name] [ "!" conversion] [ ":" format_spec] "}"
# где:
# - field_name - это *args и(или) **kwargs
# - conversion - это 'r' или 'с' или 'a'
# - format_spec - это Спецификация формата Mini-Language

Спецификация формата Mini-Language подробно описана во встроенной функции format().


Примеры форматирования строк.

Доступ к аргументам по позиции:

>>> '{0}, {1}, {2}'.format('a', 'b', 'c')
# 'a, b, c'
>>> '{}, {}, {}'.format('a', 'b', 'c')  # 3.1+ only
# 'a, b, c'
>>> '{2}, {1}, {0}'.format('a', 'b', 'c')
# 'c, b, a'
>>> '{2}, {1}, {0}'.format(*'abc')      # unpacking argument sequence
# 'c, b, a'
>>> '{0}{1}{0}'.format('abra', 'cad')   # arguments' indices can be repeated
# 'abracadabra'

Доступ к аргументам по имени:

>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
# 'Coordinates: 37.24N, -115.81W'
>>> coord = {'latitude': '37.24N', 'longitude': '-115.81W'}
>>> 'Coordinates: {latitude}, {longitude}'.format(**coord)
# 'Coordinates: 37.24N, -115.81W'

Доступ к атрибутам аргументов:

>>> c = 3-5j
>>> ('The complex number {0} is formed from the real part {0.real} '
...  'and the imaginary part {0.imag}.').format(c)
# 'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.'
>>> class Point:
...     def __init__(self, x, y):
...         self.x, self.y = x, y
...     def __str__(self):
...         return 'Point({self.x}, {self.y})'.format(self=self)
...
>>> str(Point(4, 2))
# 'Point(4, 2)'

Доступ к элементам аргументов:

>>> coord = (3, 5)
>>> 'X: {0[0]};  Y: {0[1]}'.format(coord)
# 'X: 3;  Y: 5'

Замена %s и %r:

>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
# "repr() shows quotes: 'test1'; str() doesn't: test2"

Выравнивание текста и указание ширины:

>>> '{:<30}'.format('left aligned')
# 'left aligned                  '
>>> '{:>30}'.format('right aligned')
# '                 right aligned'
>>> '{:^30}'.format('centered')
# '           centered           '
>>> '{:*^30}'.format('centered')  # use '*' as a fill char
# '***********centered***********'

Замена %+f, %-f и указание знака: %f

>>> '{:+f}; {:+f}'.format(3.14, -3.14)  # show it always
# '+3.140000; -3.140000'
>>> '{: f}; {: f}'.format(3.14, -3.14)  # show a space for positive numbers
# ' 3.140000; -3.140000'
>>> '{:-f}; {:-f}'.format(3.14, -3.14)  # show only the minus -- same as '{:f}; {:f}'
# '3.140000; -3.140000'

Замена %x и %o преобразование значения в разные базы:

>>> # format also supports binary numbers
>>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)
# 'int: 42;  hex: 2a;  oct: 52;  bin: 101010'
>>> # with 0x, 0o, or 0b as prefix:
>>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
# 'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'

Используя запятую в качестве разделителя тысяч:

>>> '{:,}'.format(1234567890)
# '1,234,567,890'

Выражение в процентах:

>>> points = 19
>>> total = 22
>>> 'Correct answers: {:.2%}'.format(points/total)
# 'Correct answers: 86.36%'

Использование специфичного для типа форматирования:

>>> import datetime
>>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)
>>> '{:%Y-%m-%d %H:%M:%S}'.format(d)
# '2010-07-04 12:15:58'

Вложенные аргументы и более сложные примеры:

>>> for align, text in zip('<^>', ['left', 'center', 'right']):
...     '{0:{fill}{align}16}'.format(text, fill=align, align=align)
...
# 'left<<<<<<<<<<<<'
# '^^^^^center^^^^^'
# '>>>>>>>>>>>right'

>>> octets = [192, 168, 0, 1]
>>> '{:02X}{:02X}{:02X}{:02X}'.format(*octets)
# 'C0A80001'
>>> int(_, 16)
# 3232235521

>>> width = 5
>>> for num in range(5,12): 
...     for base in 'dXob':
...         print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ')
...     print()
...
#     5     5     5   101
#     6     6     6   110
#     7     7     7   111
#     8     8    10  1000
#     9     9    11  1001
#    10     A    12  1010
#    11     B    13  1011