Template Strings — нові рядки-шаблони у Python 3.14
By Volodymyr Obrizan on Травень 15, 2025 · Прочитати цю публікацію іншими мовами: Russian English
У 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