Класс 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