
Python
Master custom format specifications, internationalization, and performance optimization for string formatting.
# Format spec: [fill][align][sign][#][0][width][grouping_option][.precision][type]
# Alignment and fill
value = "center"
print(f"{value:_^20}") # _____center______
print(f"{value:>20}") # ___________center
print(f"{value:<20}") # center__________
# Number formatting
pi = 3.14159
print(f"{pi:10.3f}") # " 3.142"
print(f"{pi:+.2f}") # "+3.14"
print(f"{pi:.2%}") # "314.16%"
# Binary, hex, octal
num = 255
print(f"{num:b}") # 11111111
print(f"{num:x}") # ff
print(f"{num:o}") # 377
print(f"{num:#x}") # 0xff
# Grouping options
large = 1234567
print(f"{large:,}") # 1,234,567
print(f"{large:_}") # 1_234_567
print(f"{large:,}") # 1,234,567class Currency:
def __init__(self, value, currency="USD"):
self.value = value
self.currency = currency
def __format__(self, spec):
"""Custom format method"""
if spec == "":
return f"${self.value:.2f}"
elif spec == "EUR":
return f"β¬{self.value:.2f}"
elif spec == "GBP":
return f"Β£{self.value:.2f}"
return str(self.value)
price = Currency(99.99)
print(f"Price: {price}") # Price: $99.99
print(f"Price: {price:EUR}") # Price: β¬99.99
print(f"Price: {price:GBP}") # Price: Β£99.99
# Date formatting with custom class
from datetime import datetime
class FormattedDate:
def __init__(self, date):
self.date = date
def __format__(self, spec):
if spec == "short":
return self.date.strftime("%m/%d/%Y")
elif spec == "long":
return self.date.strftime("%A, %B %d, %Y")
return str(self.date)
today = FormattedDate(datetime.now())
print(f"Today: {today:short}") # Today: 02/20/2026
print(f"Today: {today:long}") # Today: Friday, February 20, 2026import locale
from datetime import datetime
# Set locale
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
# Locale-aware formatting
amount = 1234.56
print(locale.format_string("%.2f", amount)) # 1234,56 (German)
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
print(locale.format_string("%.2f", amount)) # 1234.56 (English)
# Currency formatting
import babel.numbers
from babel.dates import format_date
locale_de = 'de_DE'
locale_us = 'en_US'
amount = 1234.56
print(babel.numbers.format_currency(amount, 'EUR', locale_de))
# 1.234,56 β¬
print(babel.numbers.format_currency(amount, 'USD', locale_us))
# $1,234.56
# Date localization
date = datetime(2026, 2, 20)
print(format_date(date, 'long', locale_de))
# 20. Februar 2026
print(format_date(date, 'long', locale_us))
# February 20, 2026from string import Template
# Simple templating
template = Template("Hello, $name! Your score is $score.")
result = template.substitute(name="Alice", score=95)
print(result) # Hello, Alice! Your score is 95.
# Safe substitution (doesn't raise error for missing keys)
template = Template("$greeting, $name!")
result = template.safe_substitute(greeting="Hi")
print(result) # Hi, $name!
# Advanced: Custom template delimiters
class CustomTemplate(Template):
delimiter = "%"
idpattern = r"[_a-z][_a-z0-9]*"
custom = CustomTemplate("Name: %name, Age: %age")
print(custom.substitute(name="Bob", age=30))
# Name: Bob, Age: 30import timeit
import locale
# Format methods comparison
value = 1234.56
n = 100000
# F-string
def f_string():
return f"Value: {value:.2f}"
# .format()
def method_format():
return "Value: {:.2f}".format(value)
# % formatting
def percent_format():
return "Value: %.2f" % value
# Template
from string import Template
template = Template("Value: $value")
def template_format():
return template.substitute(value=f"{value:.2f}")
print("F-string:", timeit.timeit(f_string, number=n))
print(".format():", timeit.timeit(method_format, number=n))
print("% format:", timeit.timeit(percent_format, number=n))
print("Template:", timeit.timeit(template_format, number=n))import locale
# Setup locales
de_locale = locale.locale_alias['german']
us_locale = locale.locale_alias['english']
# Collation (locale-aware sorting)
words_de = ['Γ€pfel', 'apfel', 'zebra']
words_de.sort(key=locale.strxfrm)
# Case-insensitive comparison
text1 = "StraΓe"
text2 = "STRASSE"
print(text1.casefold() == text2.casefold()) # True
# Normalize for comparison
import unicodedata
text1_norm = unicodedata.normalize("NFKD", text1)
text2_norm = unicodedata.normalize("NFKD", text2)| Concept | Remember |
|---|---|
| Format specs | Control alignment, precision, type with `:` |
| Custom __format__ | Implement for domain-specific types |
| Babel library | Use for production i18n needs |
| F-strings fastest | Typically fastest for simple cases |
| Template strings | Safe for user input; good for i18n |
Learn advanced finding and replacing techniques.
Ready to practice? Challenges | Quiz
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep β’ Build Real β’ Verify Skills β’ Launch Forward