Python 3.14 представляет мощную новую функцию: шаблонные строки (template strings), формализованные в PEP 750. В то время как f-строки
(f""
) предлагают удобную встроенную интерполяцию, они сразу же преобразуются в обычные строки, что делает невозможным извлечение метаданных, управление поведением рендеринга или проверку того, какие выражения были интерполированы.
Шаблонные строки (t""
) решают эту проблему, создавая структурированный объект (Template
) вместо строки. Это дает разработчикам программный доступ к:
- Исходному выражению (
{username}
) - Его вычисленному значению (
'abhimanyu'
) - Параметрам форматирования (
:.2f
,!r
и т.д.)
Результат: основа для создания более безопасной, проверяемой и повторно используемой обработки строк, особенно полезная для логирования, систем шаблонизации, веб-вывода и структурированных конвейеров.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Почему бы не использовать просто f-строки?
Многие случаи использования (HTML, shell-команды, логи) кажутся выполнимыми с помощью f-строк
. Так почему же стоит переключиться?
Потому что t-строки
это:
f-строки дают вам результат. t-строки дают вам контроль.
Начало работы
Перед погружением в реальные примеры использования, вот как работает базовая t-строка
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from string.templatelib import Template user = "abhimanyu" template = t"Hello, {user}" print(template.strings) # Вывод: ('Hello, ', '') print(template.interpolations[0].expression) # Вывод: 'user' print(template.interpolations[0].value) # Вывод: 'abhimanyu' |
Вместо прямого преобразования в "Hello, abhimanyu"
, шаблон дает вам структурированный доступ к:
- Фрагментам строки (
"Hello, "
) - Интерполированной переменной (
user
) - Её текущему значению (
'abhimanyu'
)
Пример 1: Санитизация пользовательского ввода в shell-командах
При динамическом создании shell-команд (например, в сценариях автоматизации) прямая вставка пользовательского ввода с использованием f-строк
может привести к инъекциям или нарушению кавычек:
1 |
command = f'ls "{path}"' # f-строка преобразуется немедленно — нет возможности проверить `path` позже |
Решение:
Используйте t-строку
для отложенного рендеринга и санитизации входных значений перед окончательным построением:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from string.templatelib import Template, Interpolation def build_command(template: Template) -> str: def sanitize(val): return str(val).replace('"', '\\"') # простой escape кавычек return "".join( sanitize(item.value) if isinstance(item, Interpolation) else item for item in template ) command = "ls" path = "/var/www" print(build_command(t'{command} "{path}"')) |
Вывод:
1 |
ls "/var/www" |
- С шаблонными строками значения всё ещё разделены в момент рендеринга, что позволяет выполнять безопасную предварительную обработку.
Пример 2: Структурированное логирование с встроенным контекстом
Традиционные строки логов смешивают человекочитаемый и машиночитаемый вывод, что затрудняет извлечение полей для анализа:
1 2 |
# f-строка: Невозможно чисто извлечь пары ключ-значение logline = f"User {user} did {action}" |
Решение:
Шаблонные строки позволяют получить прямой доступ ко всем интерполированным значениям и использовать их для создания структурированных логов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import json from string.templatelib import Template, Interpolation class DebugLog: def __init__(self, template: Template): self.template = template def __str__(self): message = "".join( str(item.value) if isinstance(item, Interpolation) else item for item in self.template ) fields = { item.expression: item.value for item in self.template if isinstance(item, Interpolation) } return f"{message} | {json.dumps(fields)}" action = "deploy" env = "staging" version = "v2.3.1" log = DebugLog(t"Action: {action}, Environment: {env}, Version: {version}") print(log) |
Вывод:
1 |
Action: deploy, Environment: staging, Version: v2.3.1 | {"action": "deploy", "env": "staging", "version": "v2.3.1"} |
- Это значительно упрощает парсинг логов, настройку оповещений и создание дашбордов — не требуется дополнительный парсинг или дублирование данных.
Пример 3: Рендеринг безопасного HTML-контента
Отображение пользовательского ввода в HTML (например, в панелях администратора, отчетах) может нарушить макет или, что еще хуже, внедрить вредоносный контент.
1 2 |
# Опасно, если ввод не обработан f"<div>{user_input}</div>" |
Решение:
Обработка интерполированных значений перед рендерингом:
1 2 3 4 5 6 7 8 9 10 11 12 |
def safe_html(template: Template) -> str: def escape(val): return str(val).replace("<", "<").replace(">", ">") return "".join( escape(item.value) if isinstance(item, Interpolation) else item for item in template ) user_input = "<script>alert(1)</script>" print(safe_html(t"<div>{user_input}</div>")) |
Вывод:
1 |
<div><script>alert(1)</script></div> |
Теперь у вас есть полный контроль над тем, как и когда происходит санитизация, без изменения входных данных или их источника.
Пример 4: Кастомный рендер, эмулирующий f-строки
f-строки скрывают поведение форматирования внутренне. Нет возможности переопределить, как работают преобразования вроде !r
, !s
или :.2f
.
Решение:
Создание пользовательского рендерера с использованием метаданных из каждой Interpolation
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
from typing import Literal from string.templatelib import Interpolation, Template def convert(value, conversion: Literal["a", "r", "s"] | None) -> str: return { "a": ascii, "r": repr, "s": str, None: lambda x: x }[conversion](value) def render(template: Template) -> str: parts = [] for item in template: if isinstance(item, str): parts.append(item) elif isinstance(item, Interpolation): val = convert(item.value, item.conversion) parts.append(format(val, item.format_spec)) return "".join(parts) name = "admin" score = 97.438 print(render(t"User: {name!r}, Score: {score:.1f}")) |
Вывод:
1 |
User: 'admin', Score: 97.4 |
Это позволяет реализовать поведение f-строк
или расширить его в соответствии с вашей логикой форматирования или доменно-специфическими правилами.
Пример 5: Динамическое объединение шаблонов
Возможно, вы захотите создать полный шаблон, комбинируя более мелкие части, особенно в генераторах конфигураций, повторно используемых UI-компонентах или динамических конструкторах логов.
С f-строками
это невозможно, так как они обрабатываются немедленно:
1 2 |
# f-строка: это не объединится как повторно используемые компоненты f"Stage: " + f"{env}" |
Решение:
Шаблонные строки позволяют выполнять композицию, Template + Template
или Template + str
возвращает новый объект Template
:
1 2 3 4 5 6 7 8 9 10 |
from string.templatelib import Interpolation env = "prod" # Должно быть определено *до* t-строки t1 = t"Stage: " t2 = t"{env}" combined = t1 + t2 # Рендеринг результата print("".join(str(item.value if isinstance(item, Interpolation) else item) for item in combined)) |
Вывод:
1 |
Stage: prod |
⚠️ Важно: интерполяции вычисляются немедленно
Как и в случае с f-строками
, t-строки
вычисляют выражения в момент создания строки, а не при её рендеринге:
1 2 3 4 5 |
env = "staging" t = t"{env}" env = "prod" # Последующее изменение не влияет print(t.interpolations[0].value) |
Вывод:
1 |
staging |
Это означает:
- Всегда определяйте переменные до их использования внутри литерала
t""
- Шаблонные строки — это не ленивые шаблоны; это структурированные снимки выражений и их вычисленных значений
Используйте
t-строки
, когда хотите комбинировать шаблоны, проверять значения или преобразовывать вывод.
Не ожидайте, что они будут повторно вычислять выражения во время рендеринга, они фиксируют состояние один раз, а не по запросу.
Заключительные мысли
Шаблонные строки в Python 3.14 — это не замена f-строкам
, а их эволюция для более продвинутых и контролируемых сценариев использования.
Если f-строки
отдают приоритет простоте и немедленному выводу, то t-строки
фокусируются на структуре, безопасности и гибкости. Они позволяют проверять выражения, изменять поведение рендеринга, санитизировать значения на лету и повторно использовать шаблоны как объекты, а не статический текст.
Если вы работаете над:
- Фреймворками для логирования, которые извлекают значения полей
- Движками шаблонизации, где пользовательский ввод должен проходить валидацию
- DSL или инструментами автоматизации, которые создают команды или конфигурации
- Любой системой, где как строится строка имеет такое же значение, как и что она в итоге представляет
то t-строки
— правильный инструмент для вас.
Используйте f-строки
, когда всё, что вам нужно — это строка.
Используйте t-строки
, когда вам нужен контроль до финализации строки.
Часто задаваемые вопросы
Что такое шаблонные строки (t»») в Python 3.14, и чем они отличаются от f-строк?
Шаблонные строки (t""
) возвращают структурированный объект Template
вместо обычной строки. В отличие от f-строк, которые сразу создают строку, t-строки дают доступ к метаданным интерполяции, таким как имена переменных, вычисленные значения и инструкции форматирования. Это позволяет выполнять интроспекцию, трансформацию и более безопасный рендеринг.
Когда следует использовать шаблонные строки вместо f-строк?
Используйте шаблонные строки, когда:
- Вам нужно санитизировать или проверять интерполированные значения
- Вы создаете структурированные логи, shell-команды или HTML безопасным способом
- Вы хотите отложить рендеринг или настроить поведение вывода
- Вы динамически составляете строки из более мелких частей
Используйте f-строки, когда вам нужен только немедленный вывод строки.
Вычисляются ли шаблонные строки лениво?
Нет. Как и f-строки, шаблонные строки немедленно вычисляют свои выражения в момент создания строки. Это означает, что все используемые переменные должны быть уже определены, а изменения переменных после создания t-строки не повлияют на сохраненные в шаблоне значения.
Можно ли создавать пользовательские рендереры с помощью шаблонных строк?
Да. Вы можете получить доступ к отдельным интерполяциям (их значениям, флагам преобразования и спецификаторам форматирования) и создать пользовательскую логику рендеринга. Это полезно для воспроизведения или расширения поведения f-строк, например, для переопределения того, как интерпретируются !r
или :.2f
.
Каковы практические случаи использования шаблонных строк в Python 3.14?
Основные случаи использования включают:
- Безопасная генерация shell-команд (с санитизацией ввода)
- Структурированное логирование (представление полей как данных, а не просто строк)
- HTML-шаблонизация с безопасным экранированием
- Пользовательские DSL или генераторы конфигураций
- Составные строковые шаблоны для повторного использования в различных системах

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»