Template Method in Python

Regular Expressions Mar 20, 2026

Template Method in Python

The Template Method (via Python’s string.Template class) is a safe, flexible, and readable way to perform string substitution using named placeholders. Unlike f-strings or .format(), it is designed for user-provided templates and prevents accidental code injection. In data science it is perfect for generating dynamic reports, SQL queries, email templates, configuration strings, and regex-ready patterns where the template comes from external sources or users.

TL;DR — Template Method Key Points

  • from string import Template
  • $var or ${var} placeholders
  • template.substitute(**kwargs) or .safe_substitute()
  • Safer than f-strings for untrusted input
  • Great for reusable templates in reports and pipelines

1. Basic Template Method

from string import Template

# Template does not understand format specs like :.2f, so format the number first
t = Template("User $name achieved $score% with model $model")

result = t.substitute(
    name="Alice",
    score=f"{95.75:.2f}",
    model="random_forest"
)
print(result)

2. Real-World Data Science Examples

import pandas as pd
from string import Template

# Demo file so this example runs as-is (in your project this is your real results file)
pd.DataFrame({
    "model_name": ["XGBoost", "RandomForest", "LogReg"],
    "accuracy": [92.5, 89.123, 84.3],
    "dataset": ["customer_churn", "fraud", "customer_churn"],
}).to_csv("model_results.csv", index=False)

# Demo file so this example runs as-is (in your project this is your real results file)
pd.DataFrame({
    "model_name": ["XGBoost", "RandomForest", "LogReg"],
    "accuracy": [92.5, 89.123, 84.3],
    "dataset": ["customer_churn", "fraud", "customer_churn"],
}).to_csv("model_results.csv", index=False)

df = pd.read_csv("model_results.csv")

template_str = "Model $model_name achieved $accuracy% on dataset $dataset"
t = Template(template_str)

# Apply template row by row
df["report"] = df.apply(
    lambda row: t.substitute(
        model_name=row.model_name,
        accuracy=f"{row.accuracy:.2f}",
        dataset=row.dataset
    ), axis=1
)
print(df["report"].tolist())

# Safe substitution (no KeyError if key missing)
print(t.safe_substitute(model_name="XGBoost", accuracy=92.5))

3. Advanced Use Cases with Regex

# Build dynamic regex pattern from a template
regex_template = Template(r"Order ID:\s*$order_id\b")
pattern = regex_template.substitute(order_id=r"\d+")

import re
matches = re.findall(pattern, "Order ID: 12345, Order ID: 98765")
print(pattern, matches)

4. Best Practices in 2026

  • Use safe_substitute() when templates come from users or files
  • Define common templates as constants or load from config files
  • Combine with pandas .apply() for vectorized report generation
  • Use ${var} syntax for clarity when placeholders are adjacent to text
  • Pair with Regular Expressions for advanced pattern building and validation

When Template Is the Right Choice

string.Template uses $name placeholders and does not evaluate expressions or format specifications. That limitation is its strength: templates written by users or stored in files cannot access attributes or run code, unlike str.format, which can read attributes such as {obj.__class__}.

substitute raises KeyError for a missing name, while safe_substitute leaves the placeholder in place. A dollar sign is written as $$, and ${name} separates the name from following letters.

Because Template cannot format numbers, prepare the values first with f-strings or round, then substitute the finished strings.

Worked Example: Safe Customer Messages

A stored message template is filled with prepared values.

from string import Template

msg = Template("Hi $name, your ${plan}ly bill is $$${amount}.")
values = {"name": "Hina", "plan": "month", "amount": f"{1234.5:,.2f}"}

print(msg.substitute(values))
print(msg.safe_substitute(name="Omar"))
try:
    msg.substitute(name="Omar")
except KeyError as e:
    print("Missing:", e)

${plan} is followed directly by "ly", $$ prints a literal dollar sign, and the amount is formatted before substitution. safe_substitute keeps unknown placeholders, while substitute reports the missing key.

Practical Tips

Store templates in text files or a database table and load them at runtime. Because Template never runs code, the text can be edited by non-programmers with little risk.

Validate templates at load time by calling safe_substitute with sample values and checking that no $ placeholders remain.

Keep all value formatting in Python, before substitution, so numbers and dates look the same in every message.

Common Mistakes

  • Expecting format specifications such as :.2f to work.
  • Forgetting $$ for a literal dollar sign.
  • Using substitute when some values may be missing.
  • Using str.format on templates from untrusted sources.

Quick Summary

  • Template uses $name placeholders.
  • It does not evaluate expressions.
  • safe_substitute keeps missing names.
  • Format numbers before substituting.

Conclusion

The Template Method (string.Template) offers a clean, safe, and reusable way to handle string interpolation in Python. In 2026 data science projects it shines for generating reports, SQL queries, dynamic regex patterns, and configuration strings. It is more secure than f-strings for external templates and integrates beautifully with pandas and the re module.

Next steps:

  • Convert one of your current string-formatting blocks to a Template for better maintainability and safety

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices