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 выбрать и скачать установщик для вашей операционной системы:

Screenshot 2025-05-14 at 20.53.14.png

После установки бета-версия Python 3.14 будет доступна по команде python3.14. Можно проверить версию с помощью команды в терминале:

$ python3.14 --version

Python 3.14.0b1

Источники

Telegram
Viber
LinkedIn
WhatsApp

Комментарии

Войти чтобы оставить комментарий.

← Назад к блогу