Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 63
Текст из файла (страница 63)
Вслед за идентификатором символа подстановки, через двоеточие, можно указать спецификатор формата, определяющий ширину поля вывода, выравнивание и код типазначения. Ниже приводится формальный синтаксис спецификатора формата:{fieldname!conversionflag:formatspec}Поля спецификатора имеют следующий смысл:•• fieldname – порядковый номер или имя именованного аргумента, за которым может следовать необязательное имя «.name» атрибута или индекс«[index]» элемента.•• conversionflag – может быть r, s или a, которые определяют применениек значению встроенной функции repr, str или ascii соответственно.•• formatspec – определяет способ представления значения, описывает такиехарактеристики представления, как ширина поля вывода, выравнивание,дополнение, количество знаков после десятичной точки и так далее, и завершается необязательным кодом типа значения.Поле formatspec, следующее за двоеточием, в общем виде имеет следующийсинтаксис (квадратные скобки окружают необязательные компоненты и неимеют отношения к синтаксису поля):[[fill]align][sign][#][0][width][.precision][typecode]В поле align может указываться символ <, >, = или ^, обозначающий выравнивание по левому или по правому краю, дополнение после символа знака числаили выравнивание по центру соответственно.
Спецификатор формата formatspec может также содержать вложенные {} строки форматирования с именамиполей, чтобы извлекать значения из списка аргументов динамически (практически так же, как символ * в операторе форматирования).Подробное описание синтаксиса и полный список допустимых кодов типа вынайдете в руководстве по стандартной библиотеке языка Python – этот списокпрактически полностью совпадает со списком спецификаторов, используемыхв операторе форматирования % и перечисленных в табл. 7.4. Дополнительно метод format позволяет использовать код типа «b» для отображения целых чиселв двоичном формате (эквивалент вызову встроенной функции bin).
Кроме того,код типа «%» используется для отображения символа процента, а для отображения десятичных целых чисел допускается использовать только код «d»(коды «i» и «u» считаются недопустимыми).В следующем примере спецификатор {0:10} предписывает вывести значениепервого позиционного аргумента в поле шириной 10 символов.
Спецификатор242Глава 7. Строки{1:<10} предписывает вывести значение второго позиционного аргумента в полешириной 10 символов, с выравниванием по левому краю, а спецификатор{0.platform:>10} предписывает вывести значение атрибута platform первого позиционного аргумента в поле шириной 10 символов, с выравниванием по правомукраю:>>> ‘{0:10} = {1:10}’.format(‘spam’, 123.4567)‘spam = 123.457’>>> ‘{0:>10} = {1:<10}’.format(‘spam’, 123.4567)‘ spam = 123.457 ‘>>> ‘{0.platform:>10} = {1[item]:<10}’.format(sys, dict(item=’laptop’))‘ win32 = laptop ‘Для вывода вещественных чисел метод format поддерживает те же самые кодытипов и параметры форматирования, что и оператор %. Так, в следующем примере спецификатор {2:g} предписывает вывести третий аргумент, отформатированный в соответствии с представлением вещественных чисел по умолчанию, предусмотренным кодом «g».
Спецификатор {1:.2f} предписывает использовать формат «f» представления вещественных чисел с двумя знаками последесятичной точки, а спецификатор {2:06.2f} дополнительно ограничивает ширину поля вывода 6 символами и предписывает дополнить число нулями слева:>>> ‘{0:e}, {1:.3e}, {2:g}’.format(3.14159, 3.14159, 3.14159)‘3.141590e+00, 3.142e+00, 3.14159’>>> ‘{0:f}, {1:.2f}, {2:06.2f}’.format(3.14159, 3.14159, 3.14159)‘3.141590, 3.14, 003.14’Метод format поддерживает также возможность вывода чисел в шестнадцатеричном, восьмеричном и двоичном представлениях.
Фактически строка формата может служить альтернативой использованию некоторых встроенныхфункций:>>> ‘{0:X}, {1:o}, {2:b}’.format(255, 255, 255) # Шестнадцатеричное,‘FF, 377, 11111111’# восьмеричное и двоичное представление>>> bin(255), int(‘11111111’, 2), 0b11111111 # Другие способы работы с (‘0b11111111’, 255, 255)# двоичным представлением>>> hex(255), int(‘FF’, 16), 0xFF # Другие способы работы с(‘0xff’, 255, 255)# шестнадцатеричным представлением>>> oct(255), int(‘377’, 8), 0o377, 0377 # Другие способы работы с(‘0377’, 255, 255, 255)# восьмеричным представлением# 0377 допустимо только в 2.6, но не в 3.0!Параметры форматирования можно указывать непосредственно в строке формата или динамически извлекать из списка аргументов, с помощью синтаксисавложенных конструкций, практически так же, как с помощью символа звездочки в операторе форматирования %:>>> ‘{0:.2f}’.format(1 / 3.0) # Параметры определены непосредственно‘0.33’# в строке формата>>> ‘%.2f’ % (1 / 3.0)‘0.33’>>> ‘{0:.{1}f}’.format(1 / 3.0, 4) # Значение извлекается из списка аргументов243Метод форматирования строк‘0.3333’>>> ‘%.*f’ % (4, 1 / 3.0)‘0.3333’# Как то же самое делается в выраженияхНаконец, в Python 2.6 и 3.0 появилась новая встроенная функция format, которая может использоваться для форматирования одиночных значений.
Онаможет рассматриваться как более компактная альтернатива методу formatи напоминает способ форматирования единственного значения с помощью оператора %:>>> ‘{0:.2f}’.format(1.2345)‘1.23’>>> format(1.2345, ‘.2f’)‘1.23’>>> ‘%.2f’ % 1.2345‘1.23’# Строковый метод# Встроенная функция# Выражение форматированияС технической точки зрения, встроенная функция format вызывает метод __format__ объекта, который в свою очередь вызывает метод str.format каждогоформатируемого элемента.
Однако эта функция имеет не такой компактныйсинтаксис, как оригинальный оператор %, что ведет нас к следующему разделу.Сравнение с оператором форматирования %Если вы внимательно прочитали предыдущие разделы, вы могли заметить,что, по крайней мере, ссылки на позиционные аргументы и ключи словарейв строковом методе format выглядят почти так же, как в операторе форматирования %, особенно когда используются дополнительные параметры форматирования и коды типов значений. В действительности, в общем случае применениеоператора форматирования выглядит проще, чем вызов метода format, особеннопри использовании универсального спецификатора формата %s:print(‘%s=%s’ % (‘spam’, 42))# 2.X+ выражение форматированияprint(‘{0}={1}’.format(‘spam’, 42)) # 3.0 (и 2.6) метод formatКак вы увидите чуть ниже, в более сложных случаях оба способа имеют почтиодинаковую сложность (сложные задачи обычно сложны сами по себе, независимо от используемого подхода), поэтому некоторые считают format в значительной степени избыточным.С другой стороны, метод format предлагает дополнительные потенциальныепреимущества.
Например, оператор % не позволяет использовать именованныеаргументы, ссылки на атрибуты и выводить числа в двоичном представлении,хотя возможность использования словарей в операторе % помогает добиться техже целей. Чтобы увидеть сходные черты между этими двумя приемами, сравните следующие примеры использования оператора % с аналогичными примерами использования метода format, представленными выше:# Основы: с оператором % вместо метода format()>>> template = ‘%s, %s, %s’>>> template % (‘spam’, ‘ham’, ‘eggs’) # Позиционные параметры‘spam, ham, eggs’>>> template = ‘%(motto)s, %(pork)s and %(food)s’>>> template % dict(motto=’spam’, pork=’ham’, food=’eggs’) # Ключи словаря‘spam, ham and eggs’244Глава 7.
Строки>>> ‘%s, %s and %s’ % (3.14, 42, [1, 2])‘3.14, 42 and [1, 2]’# Произвольные типы# Использование ключей, атрибутов и смещений>>> ‘My %(spam)s runs %(platform)s’ % {‘spam’: ‘laptop’, ‘platform’: sys.platform}‘My laptop runs win32’>>> ‘My %(spam)s runs %(platform)s’ % dict(spam=’laptop’, platform=sys.platform)‘My laptop runs win32’>>> somelist = list(‘SPAM’)>>> parts = somelist[0], somelist[-1], somelist[1:3]>>> ‘first=%s, last=%s, middle=%s’ % parts“first=S, last=M, middle=[‘P’, ‘A’]”Когда требуется добиться более сложного форматирования, эти два подходастановятся почти равными в смысле сложности, хотя, если сравнить следующие примеры использования оператора % с аналогичными примерами использования метода format, представленными выше, опять можно заметить, чтооператор % выглядит несколько проще и компактнее:# Специальные приемы форматирования>>> ‘%-10s = %10s’ % (‘spam’, 123.4567)‘spam= 123.4567’>>> ‘%10s = %-10s’ % (‘spam’, 123.4567)‘spam = 123.4567 ‘>>> ‘%(plat)10s = %(item)-10s’ % dict(plat=sys.platform, item=’laptop’)‘win32 = laptop‘# Вещественные числа>>> ‘%e, %.3e, %g’ % (3.14159, 3.14159, 3.14159)‘3.141590e+00, 3.142e+00, 3.14159’>>> ‘%f, %.2f, %06.2f’ % (3.14159, 3.14159, 3.14159)‘3.141590, 3.14, 003.14’# Числа в шестнадцатеричном и восьмеричном представлениях, но не в двоичном>>> ‘%x, %o’ % (255, 255)‘ff, 377’Метод format имеет ряд дополнительных особенностей, которые не поддерживаются оператором %, но даже когда требуется реализовать еще более сложноеформатирование, оба подхода выглядят примерно одинаковыми в смысле сложности.
Например, ниже демонстрируются два подхода к достижению одинаковых результатов – при использовании параметров, определяющих ширинуполей и выравнивание, а также различных способов обращения к атрибутам:# В обоих случаях фактические значения определяются непосредственно в операции>>> import sys>>> ‘My {1[spam]:<8} runs {0.platform:>8}’.format(sys, {‘spam’: ‘laptop’})‘My laptop runs win32’Метод форматирования строк245>>> ‘My %(spam)-8s runs %(plat)8s’ % dict(spam=’laptop’, plat=sys.platform)‘My laptop runs win32’На практике фактические значения редко определяются непосредственнов операции форматирования, как здесь.