Python Basics — String Formatting Deep Dive
String Formatting Deep Dive
Beyond f-strings and str.format(), Python offers additional formatting tools for specialized needs.
Template Strings
The string module provides Template — a simpler, safer alternative for user-provided templates:
from string import Template
t = Template("Hello, $name! You have $count messages.")
result = t.substitute(name="Alice", count=5)
print(result) # Hello, Alice! You have 5 messages.
safe_substitute()
Won’t raise an error for missing placeholders:
from string import Template
t = Template("Hello, $name! Your role is $role.")
print(t.safe_substitute(name="Alice"))
# Hello, Alice! Your role is $role.
When to Use Template Strings
- User-supplied format strings (prevents code injection)
- Simple key-value replacement
- When you don’t need expressions or format specs
# f-strings can execute code — risky with user input
# template = f"{user_input}" # DANGER if user_input is malicious
# Template strings are safe
from string import Template
t = Template(user_input) # Only does simple substitution
textwrap Module
For formatting paragraphs and indented text:
import textwrap
long_text = "Python is a versatile programming language that is widely used in web development, data science, artificial intelligence, and automation. It was created by Guido van Rossum and first released in 1991."
# Wrap to 40 characters
wrapped = textwrap.fill(long_text, width=40)
print(wrapped)
Output:
Python is a versatile programming
language that is widely used in web
development, data science, artificial
intelligence, and automation. It was
created by Guido van Rossum and first
released in 1991.
textwrap Functions
import textwrap
text = " Hello, World! "
# Remove common leading whitespace
code = """
def hello():
print("hi")
"""
print(textwrap.dedent(code))
Output:
def hello():
print("hi")
import textwrap
# Indent every line
text = "Line 1\nLine 2\nLine 3"
print(textwrap.indent(text, ">>> "))
Output:
>>> Line 1
>>> Line 2
>>> Line 3
import textwrap
# Shorten (truncate with placeholder)
long = "This is a very long string that needs to be shortened"
print(textwrap.shorten(long, width=30))
# This is a very long [...]
Building Formatted Tables
Simple Table with f-strings
data = [
("Product", "Price", "Qty"),
("Widget", 9.99, 100),
("Gadget", 24.95, 50),
("Doohickey", 4.50, 200),
]
# Header
h = data[0]
print(f"{h[0]:<12} {h[1]:>8} {h[2]:>5}")
print("-" * 27)
# Rows
for name, price, qty in data[1:]:
print(f"{name:<12} ${price:>7.2f} {qty:>5}")
Output:
Product Price Qty
---------------------------
Widget $ 9.99 100
Gadget $ 24.95 50
Doohickey $ 4.50 200
Dynamic Column Widths
data = [
["Alice", "Engineering", 95000],
["Bob", "Marketing", 72000],
["Charlie", "Engineering", 105000],
["Diana", "Sales", 68000],
]
headers = ["Name", "Department", "Salary"]
# Calculate column widths dynamically
widths = [len(h) for h in headers]
for row in data:
for i, val in enumerate(row):
widths[i] = max(widths[i], len(str(val)))
# Print with calculated widths
header_fmt = " | ".join(f"{h:<{widths[i]}}" for i, h in enumerate(headers))
print(header_fmt)
print("-+-".join("-" * w for w in widths))
for row in data:
row_fmt = " | ".join(f"{str(v):<{widths[i]}}" for i, v in enumerate(row))
print(row_fmt)
Output:
Name | Department | Salary
--------+-------------+-------
Alice | Engineering | 95000
Bob | Marketing | 72000
Charlie | Engineering | 105000
Diana | Sales | 68000
String Alignment and Padding
Using str methods
# center(), ljust(), rjust()
title = "REPORT"
print(title.center(30, "=")) # ============REPORT============
print(title.ljust(30, "-")) # REPORT------------------------
print(title.rjust(30, ".")) # ........................REPORT
Using format spec
# Same results with f-strings
print(f"{'REPORT':=^30}") # ============REPORT============
print(f"{'REPORT':-<30}") # REPORT------------------------
print(f"{'REPORT':.>30}") # ........................REPORT
Multiline String Formatting
name = "Alice"
role = "Developer"
years = 5
profile = (
f"{'Name:':<10} {name}\n"
f"{'Role:':<10} {role}\n"
f"{'Years:':<10} {years}\n"
)
print(profile)
Output:
Name: Alice
Role: Developer
Years: 5
Internationalization Considerations
Number Formatting by Locale
import locale
# Set locale (varies by system)
# locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
# Manual formatting for different conventions
num = 1234567.89
# US style
print(f"US: {num:,.2f}") # 1,234,567.89
# European style (manual)
us_format = f"{num:,.2f}"
eu_format = us_format.replace(",", "X").replace(".", ",").replace("X", ".")
print(f"EU: {eu_format}") # 1.234.567,89
Unicode in Strings
# Python 3 strings are Unicode by default
emoji = "Python is fun! 🐍"
print(emoji)
# Unicode escape
print("\u2764") # ❤
print("\U0001F600") # 😀
Summary
Templatestrings are safer for user-provided format patternstextwraphandles paragraph wrapping, indentation, and truncation- Build tables with format specs and calculated column widths
- Use
center(),ljust(),rjust()or format specs for alignment - Python 3 strings are Unicode by default — emoji and special chars work natively
- Use
localemodule for region-specific number formatting
Next up: Regular Expressions Intro →