Python Template Strings — Core Concepts

Python offers several string formatting approaches: f-strings, .format(), and %-formatting. But there’s a fourth option that serves a distinct purpose: the string.Template class.

What Template Strings Are

string.Template is a class in Python’s standard library that performs simple $-based substitution. It was introduced in PEP 292 as a deliberately less powerful formatting mechanism.

The key difference from other formatting options: Template strings cannot evaluate expressions. They can only replace named placeholders with values.

Basic Usage

A template uses $identifier or ${identifier} for placeholders:

from string import Template

t = Template("Hello, $name! You have $count new messages.")
result = t.substitute(name="Alice", count=5)
# "Hello, Alice! You have 5 new messages."

Use braces when the placeholder borders other text:

t = Template("${noun}ification process complete")
t.substitute(noun="class")
# "classification process complete"

substitute vs. safe_substitute

substitute() raises KeyError if a placeholder is missing. safe_substitute() leaves missing placeholders untouched:

t = Template("$greeting, $name!")
t.safe_substitute(greeting="Hi")
# "Hi, $name!"  — $name left as-is instead of crashing

Use safe_substitute() when partial rendering is acceptable, such as multi-pass template processing.

The Security Angle

This is the primary reason Template strings exist. Consider the difference:

With f-strings or .format(), the person who writes the template string can embed arbitrary Python expressions:

# DANGEROUS if template comes from user input:
user_template = "{person.__class__.__mro__}"
user_template.format(person=some_object)
# Exposes internal class hierarchy

With Template strings, there is no expression evaluation. $person.__class__ is not valid Template syntax — it just looks for a variable literally named person.

Rule of thumb: If you control the template, use f-strings. If the template comes from outside (users, config files, databases), use string.Template.

How It Works

Templates use a simple regex under the hood to find placeholders. The default pattern matches:

PatternExampleBehavior
$identifier$nameNamed substitution
${identifier}${name}Same, with explicit braces
$$$$Literal dollar sign

The identifier must be a valid Python identifier (letters, digits, underscores, cannot start with a digit).

Customizing Templates

You can subclass Template to change the delimiter or pattern:

class PercentTemplate(Template):
    delimiter = "%"

t = PercentTemplate("Hello, %name!")
t.substitute(name="Bob")
# "Hello, Bob!"

This is useful when dollar signs appear frequently in your text (like financial documents) and you need a different marker.

When to Use Each Formatting Method

MethodSpeedPowerSafetyBest for
f-stringsFastestFull expressionsTrusted code onlyDeveloper-written strings
.format()FastAttribute access, indexingModerate riskDynamic format strings
%-formattingFastLimitedLower riskLegacy code
TemplateSlowestSubstitution onlySafestUser-supplied templates

Common Misconception

“Template strings are outdated and never needed.” They serve a specific security niche that no other Python formatting method covers. Any time a template comes from untrusted input — user-generated email templates, plugin configurations, localization files — Template strings are the correct choice.

One Thing to Remember

Template strings exist for one reason: safe substitution when the template source isn’t trusted. They deliberately sacrifice power for security, and that tradeoff is their strength.

pythonstringstemplatestext-processingsecurity

See Also

  • Python Csv Processing Learn how Python reads and writes spreadsheet-style CSV files — the universal language of data tables.
  • Python Json Handling See how Python talks to the rest of the internet using JSON — the universal language apps use to share information.
  • Python Toml Configuration Discover TOML — the config file format Python chose for its own projects, designed to be obvious and impossible to mess up.
  • Ci Cd Why big apps can ship updates every day without turning your phone into a glitchy mess — CI/CD is the behind-the-scenes quality gate and delivery truck.
  • Containerization Why does software that works on your computer break on everyone else's? Containers fix that — and they're why Netflix can deploy 100 updates a day without the site going down.