Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 64
Текст из файла (страница 64)
Чаще эти значения вычисляются заранее (например, чтобы затем подставить их все сразу в шаблон разметкиHTML�����������������������������������������������������������������). Когда мы начинаем учитывать общепринятую практику в своих примерах, сравнение метода format и оператора % становится еще более наглядным(как вы узнаете в главе 18, аргумент **data в вызове метода – это специальныйсинтаксис распаковывания ключей и значений словарей в отдельные пары«���������������������������������������������������������������������name�����������������������������������������������������������������=����������������������������������������������������������������value�����������������������������������������������������������» именованных аргументов, благодаря чему появляется возможность обращаться к ним по именам в строке формата):# В обоих случаях используются данные, собранные предварительно>>> data = dict(platform=sys.platform, spam=’laptop’)>>> ‘My {spam:<8} runs {platform:>8}’.format(**data)‘My laptop runs win32’>>> ‘My %(spam)-8s runs %(platform)8s’ % data‘My laptop runs win32’Как обычно, сообществу пользователей языка Python еще предстоит решить,что использовать лучше, – оператор %, метод format или их комбинацию.
Поэкспериментируйте с обоими способами самостоятельно, чтобы получить представление об имеющихся возможностях, а за дополнительными подробностями обращайтесь к руководству по стандартной библиотеке Python 2.6 и 3.0.Улучшения метода format в версии Python 3.1: В будущей версии 3.1 (когда писалась эта глава, она находилась еще в состоянии альфа-версии) будет добавлена возможность указыватьсимвол-разделитель разрядов в десятичных числах, что позволит вставлять запятые между трехзначными группами цифр.Для этого достаточно просто добавить запятую перед кодом типазначения, как показано ниже:>>> ‘{0:d}’.format(999999999999)‘999999999999’>>> ‘{0:,d}’.format(999999999999)‘999,999,999,999’Кроме того, в Python 3.1 имеется возможность не указывать явнопорядковые номера позиционных аргументов.
В этом случае аргументы из списка будут выбираться последовательно, однакоиспользование этой особенности может свести к нулю основноепреимущество метода format, как это описывается в следующемразделе:>>> ‘{:,d}’.format(999999999999)‘999,999,999,999’>>> ‘{:,d} {:,d}’.format(9999999, 8888888)‘9,999,999 8,888,888’246Глава 7. Строки>>> ‘{:,.2f}’.format(296999.2567)‘296,999.26’Официально в этой книге не рассматривается версия 3.1, поэтому данное примечание следует рассматривать только как предварительное.
Дополнительно в версии Python���������������������������������������� 3.1 будут ликвидированы основные проблемы производительности, наблюдающиеся в версии 3.0, связанные с файловыми операциями ввода/вывода, и делающие версию �������������������������������3.0 ���������������������������непривлекательной����������для���������������боль�����шинства применений. Дополнительные подробности вы найдетев примечаниях к выпуску 3.1. Ознакомьтесь также со сценариемformats.py в главе 24, где вы найдете приемы добавления запятых и форматирования денежных сумм вручную, которые можно использовать, пока не вышла в свет версия Python 3.1.Когда может пригодиться новый метод format?Теперь, когда я потратил столько слов, чтобы сравнить и противопоставить дваспособа форматирования, я должен объяснить, когда может пригодиться метод format. В двух словах: несмотря на то, что использование метода форматирования требует вводить больше программного кода, тем не менее:•• Он обладает некоторыми особенностями, отсутствующими в операторе форматирования %•• Позволяет более явно ссылаться на аргументы•• Вместо символа оператора используется более говорящее имя метода•• Не различает случаи, когда выполняется подстановка одного или нескольких значенийНа сегодняшний день доступны оба приема, и оператор форматирования попрежнему находит широкое применение, тем не менее метод format в конечномитоге может вытеснить его.
Но пока у вас есть выбор, поэтому, прежде чем двинуться дальше, подробнее остановимся на некоторых отличиях.Дополнительные возможностиМетод format поддерживает дополнительные возможности, недоступные прииспользовании оператора %, такие как отображение чисел в двоичном форматеи (появившаяся в Python 3.1) возможность разделения групп разрядов. Крометого, метод format позволяет напрямую обращаться к ключам словарей и атрибутам объектов в строке формата.
Однако, как мы уже видели, при использовании оператора % того же эффекта можно добиться другими способами:>>> ‘{0:b}’.format((2 ** 16) -1)‘1111111111111111’>>> ‘%b’ % ((2 ** 16) -1)ValueError: unsupported format character ‘b’ (0x62) at index 1>>> bin((2 ** 16) -1)‘0b1111111111111111’>>> ‘%s’ % bin((2 ** 16) -1)[2:]‘1111111111111111’247Метод форматирования строкСмотрите также примеры в предыдущем разделе, где проводилось сравнениеспособов, основанных на использовании ключей словаря в операторе % и ссылок на атрибуты объектов в методе format, которые в значительной степени выглядят, как вариации на одну и ту же тему.Неявные ссылки на значенияОдин из случаев, когда реализация на основе метода format выглядит более понятной, – подстановка большого количества значений в строку формата.
Так,в примере lister.py, который приводится в главе 30, выполняется подстановкашести значений в одну строку формата; в этом случае метки {i} в вызове методаformat читаются проще, чем спецификаторы %s в выражении форматирования:‘\n%s<Class %s, address %s:\n%s%s%s>\n’ % (...)# Выражение‘\n{0}<Class {1}, address {2}:\n{3}{4}{5}>\n’.format(...) # МетодС другой стороны, использование ключей словаря в операторе % позволяетв значительной степени ликвидировать эту разницу. Кроме того, этот случайможно отнести к наиболее сложным случаям форматирования, которые редко встречаются на практике, – в более типичных случаях выбор между двумя способами форматирования больше напоминает жеребьевку.
Кроме того,в версии Python 3.1 (когда писалась эта глава, она находилась еще в состоянииальфа-версии) допускается не указывать порядковые номера позиционных аргументов, что несколько снижает преимущества метода format:C:\misc> C:\Python31\python>>> ‘The {0} side {1} {2}’.format(‘bright’, ‘of’, ‘life’)‘The bright side of life’>>>>>> ‘The {} side {} {}’.format(‘bright’, ‘of’, ‘life’)# Python 3.1+‘The bright side of life’>>>>>> ‘The %s side %s %s’ % (‘bright’, ‘of’, ‘life’)‘The bright side of life’Использование возможности автоматической нумерации в версии 3.1, какв данном примере, снижает преимущества метода format.
А если сравнить операции форматирования, например, вещественных чисел, можно заметить, чтовыражение с оператором % по-прежнему получается более компактным и выглядит менее запутанным:C:\misc> C:\Python31\python>>> ‘{0:f}, {1:.2f}, {2:05.2f}’.format(3.14159, 3.14159, 3.14159)‘3.141590, 3.14, 03.14’>>>>>> ‘{:f}, {:.2f}, {:06.2f}’.format(3.14159, 3.14159, 3.14159)‘3.141590, 3.14, 003.14’>>>>>> ‘%f, %.2f, %06.2f’ % (3.14159, 3.14159, 3.14159)‘3.141590, 3.14, 003.14’Имя метода и универсальные аргументыУчитывая появление в версии 3.1 возможности автоматической нумерациипараметров, единственными потенциальными преимуществами метода format248Глава 7. Строкиостаются замена оператора % более говорящим названием метода и отсутствиеразличий между операциями с заменой единственного или нескольких значений.
Первое из этих преимуществ может заинтересовать начинающих программистов (слово «format» в тексте программы распознается проще, чем множествосимволов «%»), хотя это слишком субъективно.Последнее преимущество может оказаться более существенным – при использовании оператора форматирования % единственное значение можно указать непосредственно, но когда необходимо передать несколько значений, онидолжны быть заключены в кортеж:>>> ‘%.2f’ % 1.2345‘1.23’>>> ‘%.2f %s’ % (1.2345, 99)‘1.23 99’С технической точки зрения, оператор форматирования принимает один объект – либо само значение для подстановки, либо кортеж с одним или болееэлементами.
Фактически из-за того, что единственный элемент может передаваться либо сам по себе, либо внутри кортежа, когда возникает необходимостьотформатировать кортеж, он должен быть оформлен, как вложенный кортеж:>>> ‘%s’ % 1.23‘1.23’>>> ‘%s’ % (1.23,)‘1.23’>>> ‘%s’ % ((1.23,),)‘(1.23,)’Метод format, напротив, ликвидирует различия между этими двумя случаями,принимая одни и те же аргументы:>>> ‘{0:.2f}’.format(1.2345)‘1.23’>>> ‘{0:.2f} {1}’.format(1.2345, 99)‘1.23 99’>>> ‘{0}’.format(1.23)‘1.23’>>> ‘{0}’.format((1.23,))‘(1.23,)’Из всего вышесказанного можно сделать вывод, что метод format удобнее дляначинающих программистов и меньше способствует появлению ошибок программирования. Однако эту проблему нельзя признать существенной – есливсегда заключать значения в кортеж и не пользоваться возможностью прямойпередачи единственного значения, оператор % по сути становится похожим наметод format.
Кроме того, из-за ограниченной гибкости метода его использование приводит к увеличению объема программного кода, и учитывая, что оператор форматирования широко использовался на протяжении всей историиразвития ����������������������������������������������������������������Python����������������������������������������������������������, пока не ясно, насколько оправданно переводить существующий программный код на использование нового инструмента, о чем мы поговорим в следующем разделе.Возможный отказ в будущем?Как уже упоминалось выше, существует определенный риск, что в будущемразработчики языка Python могут объявить оператор % нерекомендуемым,Общие категории типов249в пользу метода format.