Шаблонные строки обеспечивают более простые подстановки переменных в строки.
Основным вариантом использования шаблонных строк - является интернационализация (i18n
), поскольку более простой синтаксис и функциональность шаблонов упрощают перевод, чем другие встроенные средства форматирования строк в Python.
Строки шаблона поддерживают подстановки на основе префикса $
, используя следующие правила:
$$
- заменяется одним $
;$identifier
- имя заполнителя в передаваемой строке-шаблоне, которое должно соответствовать ключу словаре. По умолчанию identifier
разрешена любая буквенно-цифровая строка ASCII без учета регистра включая подчеркивания, которая начинается с символа подчеркивания или символа ASCII. Первый неидентифицирующий символ после символа $
завершает эту спецификацию заполнителя.${identifier}
- эквивалентен $identifier
. Он необходим, если допустимые символы идентификатора следуют за заполнителем, но не являются его частью, например ${noun}ification
.Любое другое появление символа $
в строке приведет к возникновению исключения ValueError
.
Модуль string предоставляет класс шаблона, реализующий эти правила.
import string template = string.Template(template)
template
- строка шаблонаКласс шаблона Template(template)
имеет два метода, которые и выполняют подстановку значений в возвращаемый шаблон.
template.substitute(mapping={}, /, **kwds)
:Метод template.substitute()
выполняет подстановку шаблона, возвращая новую строку. mapping
- это любой словарный объект с ключами, соответствующими заполнителям в шаблоне. Кроме того, можно указать аргументы ключевых слов **kwds
, где ключевые слова являются заполнителями. Когда заданы и mapping
и **kwds
и есть дубликаты, заполнители из **kwds
имеют приоритет.
template.safe_substitute(mapping={}, /, **kwds)
:Метод template.safe_substitute()
работает как и template.substitute()
, за исключением того, что если заполнители отсутствуют в mapping
и **kwds
, вместо возбуждения исключения KeyError
, исходный заполнитель будет отображаться в результирующей строке без изменений. Кроме того, в отличие от template.substitute()
, любые другие проявления $
будут просто возвращать $
вместо появления исключения ValueError
.
Этот метод называется "безопасным", потому что он всегда пытается вернуть используемую строку вместо вызова исключения. В другом смысле safe_substitute() может быть чем угодно, кроме safe, поскольку он будет молча игнорировать искаженные шаблоны, содержащие болтающиеся разделители, несопоставимые фигурные скобки или заполнители, которые не являются допустимыми идентификаторами Python.
Экземпляры Template
также предоставляют один атрибут открытых данных:
template.template
- атрибут возвращает передаваемую строку шаблона в качестве аргумента в конструктор класса Template(template)
.>>> from string import Template >>> s = Template('$who likes $what') >>> s.substitute(who='tim', what='kung pao') # 'tim likes kung pao' >>> d = dict(who='tim') >>> Template('Give $who $100').substitute(d) # Traceback (most recent call last): # ... # ValueError: Invalid placeholder in string: line 1, col 11 >>> Template('$who likes $what').substitute(d) # Traceback (most recent call last): # ... # KeyError: 'what' >>> Template('$who likes $what').safe_substitute(d) # 'tim likes $what'
Дополнительные примеры смотрите в обзорном материале модуля string
.
Можно создавать подклассы шаблона Template
для настройки синтаксиса заполнителя, символа разделителя или всего регулярного выражения, используемого для синтаксического анализа строк шаблона.
Для этого можно переопределить эти атрибуты класса:
delimiter
- это литеральная строка, описывающая заполнитель, вводящий разделитель. Значение по умолчанию - $
. Обратите внимание, что delimiter
не должен быть регулярным выражением. Обратите внимание, что вы не можете изменить разделитель после создания класса. Другими словами, разделитель должен быть установлен в пространстве имен класса подкласса.idpattern
- это регулярное выражение, описывающее шаблон для свободных имен заполнителя, которые появляются в шаблонной строке без скобок. Значением по умолчанию является регулярное выражение (?a: [_a-z][_a-z0-9]*
). Если idpattern
задан и braceidpattern
установлен в None
, этот шаблон также будет применяться и к закрытому в скобки имени заполнителя.braceidpattern
- похож на idpattern
, но описывает шаблон для закрытых в скобки имен заполнителей. По умолчанию None
, что означает возврат к idpattern
. Другими словами один и тот же шаблон используется как внутри, так и вне скобок. Если задано, то это позволяет определять различные шаблоны для квадратных и фигурных скобок.flags
- флаги регулярного выражения, которые будут применяться при компиляции регулярного выражения, используемого для распознавания подстановок. Значением по умолчанию является re.IGNORECASE
. Обратите внимание, что re.VERBOSE
всегда будет добавляться к флагам, поэтому пользовательские idpattern
должны следовать соглашениям для подробных регулярных выражений.Например переопределим стандартный разделитель $
на %
и сделаем, что бы имена заполнителей содержали символ подчеркивания.
import string class MyTemplate(string.Template): delimiter = '%' idpattern = '[a-z]+_[a-z]+'
Так же можно переопределить весь шаблон регулярного выражения, переопределив атрибуты delimiter
и pattern
класса шаблона Template
. Атрибут pattern
должен быть объектом регулярного выражения с четырьмя именованными группами захвата.
import string # выведем pattern по умолчанию t = string.Template('$var') print(t.pattern.pattern) # \$(?: # (?P<escaped>\$) | # (?P<named>[_a-z][_a-z0-9]*) | # {(?P<braced>[_a-z][_a-z0-9]*)} | # (?P<invalid>) # )
escaped
- эта группа соответствует escape-последовательности например $$
- разделителю в шаблоне по умолчанию.named
- эта группа соответствует свободному имени заполнителя. Она не должна включать разделитель escaped
в группу захвата.braced
- эта группа соответствует закрытому в скобки имени. Она не должна включать разделитель escaped
или фигурные скобки в группу захвата.invalid
- эта группа соответствует любому другому шаблону разделителя, обычно одному разделителю, должна появляться последним в регулярном выражении.Пример переопределения шаблон для использования {{var}}
в качестве синтаксиса переменной.
import re import string # Переопределяем delimiter и pattern class NewTemplate(string.Template): delimiter = '{{' pattern = r''' \{\{(?: (?P<escaped>\{\{) | (?P<named>[_a-z][_a-z0-9]*)\}\} | (?P<braced>[_a-z][_a-z0-9]*)\}\} | (?P<invalid>) ) ''' t = NewTemplate('''Привет {{var}}!''') print(t.safe_substitute(var='Мир')) # Привет Мир!