Template Strings with string.Template
Python offers several ways to format strings: f-strings, .format(), and the older % operator. But there’s a simpler option when your needs are straightforward: string.Template. It was designed for basic string substitution without the complexity of format specifiers or expression evaluation.
Why Use Template Strings?
The Template class from the string module provides a minimal approach to string interpolation. It uses a simple $variable syntax and does not support arbitrary Python expressions, which makes it:
- Easier to read and understand
- Safer (no code execution)
- Useful for user-provided templates
- Good for generating configuration files or email templates
The tradeoff is that you cannot use expressions, formatting, or method calls inside templates.
Basic Usage
Start by importing Template and creating an instance with your template string:
from string import Template
# Create a template with placeholders
greeting = Template("Hello, $name!")
result = greeting.substitute(name="Alice")
print(result) # Hello, Alice!
The $name syntax marks placeholders that substitute() will fill in. The substitute() method takes keyword arguments matching your placeholder names.
Placeholder Variations
Templates support several placeholder styles:
from string import Template
# Simple identifier
simple = Template("Item: $item")
print(simple.substitute(item="Apple")) # Item: Apple
# Using ${name} syntax (useful adjacent to other text)
adjacent = Template("I love ${food}s!")
print(adjacent.substitute(food="pizza")) # I love pizzas!
# Empty placeholder for $$
escaped = Template("Price: $$100")
print(escaped.substitute()) # Price: $100
Use ${placeholder} when the placeholder is followed immediately by other characters that would otherwise be part of the variable name. Use $$ to produce a literal dollar sign.
Using Dictionaries
You can also pass a dictionary to substitute(), which is useful when working with dynamic data:
from string import Template
template = Template("$greeting, $name! You have $count messages.")
data = {
"greeting": "Hello",
"name": "Bob",
"count": 5
}
print(template.substitute(data)) # Hello, Bob! You have 5 messages.
This approach works well when populating templates from configuration files or API responses.
Safe Substitution
The substitute() method raises a KeyError if a placeholder lacks a value. Use safe_substitute() instead when you want missing values to remain as placeholders:
from string import Template
template = Template("Welcome to $city, $country!")
# Missing 'country' - safe_substitute leaves it as-is
result = template.safe_substitute(city="Paris")
print(result) # Welcome to Paris, $country!
This is useful when you’re not sure all placeholder values will be available.
Practical Examples
Generating Configuration Files
from string import Template
config_template = Template("""[app]
name = $app_name
version = $version
debug = $debug
environment = $env
""")
config = config_template.substitute(
app_name="myapp",
version="1.0.0",
debug="false",
env="production"
)
print(config)
Output:
[app]
name = myapp
version = 1.0.0
debug = false
environment = production
Email Templates
from string import Template
email_template = Template("""Subject: $subject
Dear $recipient,
$body
Best regards,
$sender
""")
email = email_template.substitute(
subject="Your Weekly Report",
recipient="Team",
body="Please find attached this week's summary.",
sender="Manager"
)
print(email)
Simple Reports
from string import Template
report_template = Template("""=== $title ===
Summary: $summary
Status: $status
Completed: $completed%
Next Steps:
$next_steps
""")
report = report_template.substitute(
title="Project Alpha Update",
summary="Development is on track for Q2 release.",
status="Green",
completed=75,
next_steps="- Final testing\n- Documentation\n- Deployment"
)
print(report)
Using Patterns for Multiple Substitutions
If you need to substitute the same template multiple times, create a class that inherits from Template to define a custom delimiter:
from string import Template
class MyTemplate(Template):
delimiter = "%%" # Use %% instead of $
template = MyTemplate("Hello %%name%%, your ID is %%id%%")
print(template.substitute(name="Carol", id="12345")) # Hello Carol, your ID is 12345
This is useful when your content contains $ characters that would conflict with the default delimiter.
Comparing Template to Other Methods
| Feature | Template | f-string | .format() |
|---|---|---|---|
| Expression support | None | Full | Full |
| Syntax complexity | Simple | Simple | Moderate |
| Readability | High | High | Moderate |
| Security | High (no eval) | Low | Low |
| Use case | User templates | General use | General use |
Use Template when your templates come from external sources, when simplicity matters more than formatting flexibility, or when you want to guarantee no code execution.
See Also
- fstring-guide — Python’s modern string formatting with expressions
- string-module — Module containing Template and string utilities
- format — The str.format() method for advanced formatting