Template Strings — новые строковые шаблоны в Python 3.14
By Volodymyr Obrizan on Май 15, 2025 · Прочитать этот пост на других языках: English Ukrainian
В Python 3.14 появилось новое расширение синтаксиса языка — строки-шаблоны (template strings, t-strings, t-строки). Рассмотрим, что это такое, зачем их сделали и как с ними работать.
Что такое Template Strings?
Строки-шаблоны (template strings, t-strings, t-строки) — это обобщение f-строк, в которых вместо префикса f
используется t
. Вместо того чтобы вычисляться как тип str
, t-строки вычисляются как экземпляр нового неизменяемого типа — Template
(модуль string.templatelib
).
Важно: не путать с Template Strings, которые появились в Python 2.4 ещё в 2004 году (PEP 292) и выглядят так: s = Template('$who likes $what')
.
Рассмотрим на примере, где показана эта разница между f-строками и t-строками:
name = "Volodymyr Obrizan"
f_string = f"Hello, {name}"
template = t"Hello, {name}"
print("f-string: ", f_string)
print("t-string: ", template)
Вывод в терминал:
f-string: Hello, Volodymyr Obrizan
t-string: Template(strings=('Hello, ', ''), interpolations=(Interpolation('Volodymyr Obrizan', 'name', None, ''),))
Обратите внимание, что f-строка f_string
была вычислена сразу в строку "Hello, Volodymyr Obrizan"
, а t-строка template
не была вычислена как строка, а образовала объект типа Template
. Таким образом, интерполяция (преобразование шаблона) происходит не мгновенно, а отложенно.
Как обрабатывать такие шаблоны?
Как обрабатывать такие шаблоны, чтобы получить конкретную строку с уже подставленными значениями? Алгоритм интерполяции (преобразования) должен определить пользователь.
Объект типа Template
поддерживает протокол __iter__
, то есть можно последовательно получить все части шаблона:
city = "Kharkiv"
weather = "20 C"
for item in t"Temperature in {city} is {weather}":
print(item, type(item))
Вывод в терминал:
Temperature in <class 'str'>
Interpolation('Kharkiv', 'city', None, '') <class 'string.templatelib.Interpolation'>
is <class 'str'>
Interpolation('20 C', 'weather', None, '') <class 'string.templatelib.Interpolation'>
Мы видим, что Template
построен из 4 частей:
"Temperature in "
— строка{city}
— объект типаInterpolation
" is "
— строка{weather}
— объект типаInterpolation
Используя итерацию по Template
, можно написать собственный алгоритм интерполяции таких шаблонов.
Пример интерполяции: secret_safe
Задача: при выводе в лог-файлы или на терминал желательно скрывать секреты: API-ключи, токены и т.п.
Разработаем алгоритм интерполяции шаблона secret_safe
, который должен маскировать все значения, передаваемые в шаблон. Для определения, является ли значение в шаблоне секретом, будем использовать функцию shannon_entropy(data: str) -> float
, которая вычисляет энтропию алгоритмом Шеннона. Если энтропия для строки превышает определённый порог (в примере это 3,8) и длина строки больше 10 символов, то такую строку считаем секретом (функция is_probably_secret
) и маскируем: заменяем середину секрета на звёздочки: 123******890
.
Функция secret_safe(template: Template) -> str
вычисляет шаблон в конкретную строку.
import math
from collections import Counter
from string.templatelib import Interpolation, Template
# Вычисляет энтропию Шеннона для заданной строки
def shannon_entropy(data: str) -> float:
return 0.0 if not data else -sum((count / len(data)) * math.log2(count / len(data)) for count in Counter(data).values())
# Проверяет, является ли строка, вероятно, секретной (по длине и энтропии)
def is_probably_secret(s: str, threshold: float = 3.8) -> bool:
return len(s) > 10 and shannon_entropy(s) > threshold
# Обрабатывает шаблон и маскирует значения, которые выглядят как секреты
def secret_safe(template: Template) -> str:
parts: list[str] = []
for item in template:
# Перебираем все части шаблона
match item:
# Если это обычный текстовый фрагмент
case str() as s:
parts.append(s)
# Если это интерполяция переменной
case Interpolation(value, _, _, _):
# Если значение выглядит как секрет — маскируем его
if is_probably_secret(value):
parts.append(str(item.value)[:3] + "*****" + str(item.value)[-3:])
else:
parts.append(str(item.value))
# Объединяем все части в одну строку
return "".join(parts)
Пример 1. Шаблон логина и пароля:
login = "Volodymyr"
password = "aSalDsLOgrETAreFOLMA"
signup_template = t"Hi, {login}, your password is {password}."
print(secret_safe(signup_template))
Вывод в терминал:
Hi, Volodymyr, your password is aSa*****LMA.
Пример 2. Шаблон для переменных окружения:
variables = {
"AWS_REGION": "us-west-1",
"AWS_OUTPUT_FORMAT": "json",
"AWS_ACCESS_KEY_ID": "AKIAIOSFODNN7EXAMPLE",
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
for k, v in variables.items():
print(secret_safe(t"{k}={v}"))
Вывод в терминал:
AWS_REGION=us-west-1
AWS_OUTPUT_FORMAT=json
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJa*****KEY
Как предыдущие версии реагируют на Template Strings?
Если попытаться использовать синтаксис t-строк в версиях Python 3.13 и ниже, то интерпретатор выдаст исключение SyntaxError: invalid syntax
:
File "/Users/obrizan/Projects/Experiments/template-strings/main.py", line 3
template = t"Hello, {name}"
^^^^^^^^^^^^^^^
SyntaxError: invalid syntax
Поэтому использовать этот новый синтаксис нужно осторожно. Если нужна совместимость с предыдущими версиями Python (3.13 и ниже), то придётся подождать с использованием строк-шаблонов.
Как установить Python 3.14?
Python 3.14.0b1 — это первая публичная бета-версия интерпретатора Python 3.14, которая вышла 7 мая 2025 года. Первая бета — это важная точка в разработке Python 3.14, потому что разработчики не будут добавлять никаких новых функций, только исправления ошибок. Официальный релиз версии Python 3.14.0 запланирован на 7 октября 2025 года.
Строки-шаблоны доступны в Python 3.14, а как его установить до официального выхода?
С помощью пакетного менеджера uv
Устанавливаем пакетный менеджер uv
: инструкции по установке.
Проверяем, какие версии интерпретатора Python доступны для установки. Для этого выполним команду uv python list
в терминале. Эта команда покажет, какие версии Python уже установлены и доступны для загрузки:
$ uv python list
cpython-3.14.0a6+freethreaded-macos-aarch64-none <download available>
cpython-3.14.0a6-macos-aarch64-none <download available>
cpython-3.13.3-macos-aarch64-none /opt/homebrew/bin/python3.13
cpython-3.13.3-macos-aarch64-none /opt/homebrew/bin/python3
cpython-3.13.2+freethreaded-macos-aarch64-none <download available>
cpython-3.13.2-macos-aarch64-none <download available>
cpython-3.13.1-macos-aarch64-none /usr/local/bin/python3.13
cpython-3.13.1-macos-aarch64-none /Library/Frameworks/Python.framework/Versions/3.13/bin/python3.13
cpython-3.13.1-macos-aarch64-none /Library/Frameworks/Python.framework/Versions/3.13/bin/python3
...
<другие старые версии>
На момент написания этой статьи была доступна альфа-версия Python 3.14.0a6 с идентификатором cpython-3.14.0a6-macos-aarch64-none
.
Скачаем и установим эту версию, выполнив команду uv python install cpython-3.14.0a6-macos-aarch64-none
в терминале:
$ uv python install cpython-3.14.0a6-macos-aarch64-none
Installed Python 3.14.0a6 in 2.59s
+ cpython-3.14.0a6-macos-aarch64-none
С помощью установщика
Нужно перейти на страницу Current Pre-release Testing Versions и найти ссылку на текущую бета-версию. На момент написания этой статьи была доступна бета-версия Python 3.14.0b1. Нужно перейти на соответствующую страницу и в разделе Files выбрать и скачать установщик для вашей операционной системы:
После установки бета-версия Python 3.14 будет доступна по команде python3.14
. Можно проверить версию с помощью команды в терминале:
$ python3.14 --version
Python 3.14.0b1