Python f-strings provide immediate string interpolation for everyday use, while t-strings (Python 3.14+, PEP 750) create structured Template objects ideal for safe, customizable rendering in scenarios like HTML or logging.
Core Differences
F-strings eagerly evaluate {} expressions into a final str, losing all template structure. T-strings preserve segments and interpolations as an iterable Template, allowing renderers to process values securely without direct concatenation.
Basic Example with Iteration:
name = "Alice"
age = 30
f_result = f"Hello, {name}! You are {age} years old."
print(f_result) # Hello, Alice! You are 30 years old.
print(type(f_result)) # <class 'str'>
t_result = t"Hello, {name}! You are {age} years old."
print(type(t_result)) # <class 'string.templatelib.Template'>
print(list(t_result)) # ['Hello, ', Interpolation('Alice', 'name', None, ''), '! You are ', Interpolation(30, 'age', None, ''), ' years old.']
T-strings expose components for targeted processing.
Syntax and Formatting
Format specifiers work in both, but t-strings defer final application.
Formatting Example:
pi = 3.14159
f_pi = f"Pi ≈ {pi:.2f}"
print(f_pi) # Pi ≈ 3.14
t_pi = t"Pi ≈ {pi:.2f}"
result = ""
for i, s in enumerate(t_pi.strings):
result += s
if i < len(t_pi.interpolations):
interp = t_pi.interpolations[i]
if interp.format_spec:
result += format(interp.value, interp.format_spec)
else:
result += str(interp.value)
print(result) # Pi ≈ 3.14
Consumers can override or enhance formatting in t-strings.
HTML Rendering Example
T-strings prevent XSS by enabling per-value escaping.
Safe HTML Generation:
user_name = "<script>alert('XSS')</script>"
greeting = "Welcome"
html_tmpl = t"""
<html>
<h1>{greeting}</h1>
<p>Hello, {user_name}!</p>
</html>
"""
# Custom HTML renderer (no external libs needed)
def html_render(template):
parts = []
for segment in template:
if isinstance(segment, str):
parts.append(segment)
else:
# Simulate HTML escaping
escaped = str(segment.value).replace('&', '&').replace('<', '<').replace('>', '>').replace("'", ''')
parts.append(escaped)
return ''.join(parts)
safe_html = html_render(html_tmpl)
print(safe_html)
# <html>\n <h1>Welcome</h1>\n <p>Hello, <script>alert('XSS')</script>!</p>\n</html>
This shows t-strings' strength: structure enables selective escaping.
Logging Renderer Example
Safe Logging with Context:
import datetime
timestamp = datetime.datetime.now()
user_id = "user123"
level = "ERROR"
log_tmpl = t"[{level}] User {user_id} logged in at {timestamp:%Y-%m-%d %H:%M:%S}"
def log_render(template):
parts = []
for segment in template:
if isinstance(segment, str):
parts.append(segment)
else:
parts.append(str(segment.value)) # Log-safe formatting
return ''.join(parts)
log_entry = log_render(log_tmpl)
print(log_entry) # [ERROR] User user123 logged in at 2026-01-11 13:35:00
T-strings keep logs structured yet safe.
Practical Use Cases Table
| Scenario | F-String Approach | T-String + Render Benefit |
|---|---|---|
| Debug Logging | f"{var=}" → instant string |
Custom formatters per field |
| HTML Generation | Manual escaping everywhere | Auto-escape via renderer |
| Config Templates | Direct substitution | Validate/transform values before render |
| CLI Output | Simple trusted data | Colorize/structure fields selectively |
T-strings complement f-strings by enabling secure, modular rendering without sacrificing Python's concise syntax.
Leave a Reply