'badc0ffee'
1
См. документацию Python «Форматирование строк в стиле printf»:
https://docs .python .
org/3/library/stdtypes .html#printf-style-string-formatting
58 Глава 2 • Шаблоны для чистого Python
Синтаксис «классического» форматирования строк слегка изменится,
если вы захотите выполнить многочисленные подстановки в одном-
единственном строковом значении. Поскольку оператор
%
принимает
всего один аргумент, вам необходимо обернуть правую часть в кортеж,
как здесь:
>>> 'Эй, %s! Вот ошибка 0x%x!' % (name, errno)
'Эй, Боб! Вот ошибка 0xbadc0ffee!'
Кроме того, к подстановкам переменных в своей форматной строке можно
обращаться по имени. В этом случае в оператор
%
следует передать словарь
с отображением имен на соответствующие им значения:
>>> 'Эй, %(name)s! Вот ошибка 0x%(errno)x!' % {
... "name": name, "errno": errno }
'Эй, Боб! Вот ошибка 0xbadc0ffee!'
Это облегчает поддержку ваших строк и их модификацию в будущем. Вам
не нужно волноваться о том, что порядок, в котором вы передаете значе-
ния, совпадает с порядком, на который ссылаются значения в форматной
строке. Разумеется, оборотной стороной этого приема является то, что он
требует набирать чуть больше текста.
Я уверен, вы спросите, почему такое форматирование в стиле
printf
называется «классическим» форматированием строк. Что ж, давайте
расскажу. Дело в том, что оно технически было заменено на «современ-
ное» форматирование, о котором мы собираемся поговорить уже через
минуту. Но несмотря на то что «классическому» форматированию стали
придавать меньшее значение, оно не было объявлено нерекомендуемым
для использования. И в последних версиях Python оно по-прежнему под-
держивается.
№ 2 . «Современное» форматирование строковых значений
Python 3 ввел новый способ форматирования строк, который позднее
был также перенесен в Python 2.7. Это «современное» форматирование
строк избавляется от специального синтаксиса с использованием опера-
тора
%
и делает синтаксис форматирования строк более упорядоченным.
2 .5 . Шокирующая правда о форматировании строковых значений 59
Форматирование теперь обрабатывается вызовом функции
format()
со
строковым объектом
1
.
Функция
format()
может применяться для выполнения простого позици-
онного форматирования, точно так же, как вы могли поступать в случае
с «классическим» форматированием:
>>> 'Привет, {}'.format(name)
'Привет, Боб'
Либо вы можете обращаться к подстановкам переменных по имени и ис-
пользовать их в любом порядке, в котором вы захотите. Это довольно
мощное функциональное средство языка, поскольку оно позволяет из-
менять порядок следования отображаемых элементов, не изменяя аргу-
менты, переданные в функцию форматирования:
>>> 'Эй, {name}! Вот ошибка 0x{errno:x}!'.format(
... name=name, errno=errno)
'Эй, Боб! Вот ошибка 0xbadc0ffee!'
Этот пример также показывает, как изменился синтаксис форматирова-
ния целочисленной переменной в виде шестнадцатеричной строки. Теперь
мы должны передавать спецификацию формата (format spec) путем до-
бавления суффикса «
:x
» после имени переменной.
В целом синтаксис форматной строки стал мощнее, не усложнив при этом
более простые варианты использования. Время, потраченное на подробное
изучение документации Python по мини-языку форматирования строк,
с лихвой окупится
2
.
В Python 3 «современному» форматированию строк отдается предпо-
чтение по сравнению с форматированием с использованием
%
. Однако,
начиная с Python 3.6, появился еще более оптимальный способ форма-
тирования строковых значений. И об этом способе я вам расскажу в сле-
дующем разделе.
1
См. документацию Python «str.format()»:
https://docs .python .org/3/library/string .html#format-
string-syntax
2
См. документацию Python «Синтаксис форматной строки»:
https://docs .python .org/3/
library/string .html#format-string-syntax
60 Глава 2 • Шаблоны для чистого Python
№ 3 . Интерполяция литеральных строк (Python 3 .6+)
Python 3.6 добавляет еще один способ форматирования строк, который
называется форматированными строковыми литералами (Formatted
String Literals). Этот новый способ форматирования строк позволяет ис-
пользовать выражения Python, которые встраиваются в строковые кон-
станты. Ниже дан простой пример, который поможет вам проникнуться
этим функциональным средством языка:
>>> f'Привет, {name}!'
'Привет, Боб!'
В новом синтаксисе форматирования заложена большая мощь. Поскольку
он позволяет встраивать произвольные выражения Python, вы даже може-
те выполнять локальные арифметические действия, как показано ниже:
>>> a = 5
>>> b = 10
>>> f'Пять плюс десять равняется {a + b}, а не {2 * (a + b)}.'
'Пять плюс десять равняется 15, а не 30.'
За кадром форматированные строковые литералы представляют собой
функциональное средство синтаксического анализатора Python, которое
преобразовывает
f
-строки в серию строковых констант и выражений.
Затем они объединяются, формируя окончательное строковое значение.
Предположим, что у нас есть следующая функция
greet()
, которая со-
держит
f
-строку:
>>> def greet(name, question):
... return f"Привет, {name}! Как {question}?"
...
>>> greet('Боб', 'дела')
"Привет, Боб! Как дела?"
Если эту функцию дизассемблировать и проинспектировать то, что про-
исходит за кадром, то мы увидим, что в этой функции f-строка преобра-
зовывается в нечто наподобие следующего:
2 .5 . Шокирующая правда о форматировании строковых значений 61
>>> def greet(name, question):
... return ("Привет, " + name + "! Как " +
question + "?")
На практике реализация слегка быстрее, чем эта, потому что в ней в ка-
честве оптимизации используется код операции
BUILD_STRING
1
. Но функ-
ционально они одинаковы:
>>> import dis
>>> dis.dis(greet)
2 0 LOAD_CONST 1 ('Привет, ')
2 LOAD_FAST 0 (name)
4 FORMAT_VALUE 0
6 LOAD_CONST 2 ("! Как ")
8 LOAD_FAST 1 (question)
10 FORMAT_VALUE 0
12 LOAD_CONST 3 ('?')
14 BUILD_STRING 5
16 RETURN_VALUE
Строковые литералы также поддерживают существующий синтаксис
форматных строк метода
str.format()
. Это позволяет решать те же са-
мые задачи форматирования, которые мы обсудили в предыдущих двух
Do'stlaringiz bilan baham: |