Mojo String Formatting
String formatting builds readable output by combining text with variable values. Instead of concatenating pieces manually with many + operators, formatting methods let you place values directly inside a template string. Mojo provides several approaches — from simple concatenation to Python-style format strings via Python interop.
The Envelope Analogy
Template: "Dear {name}, your balance is {amount}."
Before filling:
"Dear {name}, your balance is {amount}."
↑ ↑
placeholder placeholder
After filling (name="Alice", amount=150.0):
"Dear Alice, your balance is 150.0."
Formatting inserts values into placeholders without manual string joins.
Basic Concatenation (Simple Cases)
fn main():
var name = "Mojo"
var version = 1
var message = "Language: " + name + " v" + String(version)
print(message) # Language: Mojo v1
Concatenation works for short strings. It becomes messy with many values — use formatted approaches for anything with three or more insertions.
Building Formatted Strings with String()
fn format_score(player: String, score: Int, rank: Int) -> String:
return player + " | Score: " + String(score) + " | Rank: " + String(rank)
fn main():
print(format_score("Alice", 9500, 1)) # Alice | Score: 9500 | Rank: 1
print(format_score("Bob", 8200, 2)) # Bob | Score: 8200 | Rank: 2
Python f-Strings via Interop
Mojo's Python interop lets you use Python's powerful f-string formatting for complex output patterns.
from python import Python
fn main() raises:
var py = Python.import_module("builtins")
var name = "Alice"
var score = 95.7
var grade = "A"
# Use Python's format() function
var result = py.str("Name: {}, Score: {:.1f}, Grade: {}").format(
name, score, grade
)
print(result) # Name: Alice, Score: 95.7, Grade: A
Number Formatting
Decimal Places
from python import Python
fn main() raises:
var py = Python.import_module("builtins")
var pi = 3.141592653589793
# Round to 2 decimal places
var two_dp = py.str("{:.2f}").format(pi)
print(two_dp) # 3.14
# Round to 4 decimal places
var four_dp = py.str("{:.4f}").format(pi)
print(four_dp) # 3.1416
Thousands Separator
from python import Python
fn main() raises:
var py = Python.import_module("builtins")
var big = 1234567890
print(py.str("{:,}").format(big)) # 1,234,567,890
print(py.str("{:_}").format(big)) # 1_234_567_890
Zero Padding and Width
from python import Python
fn main() raises:
var py = Python.import_module("builtins")
# Pad number to 5 characters with zeros
for i in range(1, 6):
print(py.str("{:05d}").format(i))
Output:
00001 00002 00003 00004 00005
Table Formatting
from python import Python
fn main() raises:
var py = Python.import_module("builtins")
# Column widths: name=15, score=8, grade=6
var header = py.str("{:<15} {:>8} {:>6}").format("Name", "Score", "Grade")
print(str(header))
print("-" * 31)
var rows = [("Alice", 95, "A"), ("Bob", 82, "B"), ("Carol", 74, "C")]
for row in rows:
var line = py.str("{:<15} {:>8} {:>6}").format(
row[0], row[1], row[2]
)
print(str(line))
Output:
Name Score Grade ------------------------------- Alice 95 A Bob 82 B Carol 74 C
Alignment codes:
{:<15} left-align in field of width 15
{:>8} right-align in field of width 8
{:^10} center in field of width 10
Building a Mojo Format Helper
Wrap common formatting into a reusable Mojo function so you do not repeat the Python interop boilerplate.
from python import Python
fn fmt(template: String, *args: PythonObject) raises -> String:
var py = Python.import_module("builtins")
var result = py.str(template).format(*args)
return str(result)
fn main() raises:
print(fmt("Hello, {}!", "Mojo"))
print(fmt("{} + {} = {}", 3, 4, 7))
print(fmt("Pi ≈ {:.4f}", 3.14159))
Output:
Hello, Mojo! 3 + 4 = 7 Pi ≈ 3.1416
Formatting for Debugging
fn debug_vector(label: String, data: List[Float64]):
print(label + ": [", end="")
for i in range(len(data)):
if i > 0:
print(", ", end="")
print(data[i], end="")
print("]")
fn main():
var weights = List[Float64](0.12, 0.47, 0.85, 0.33)
debug_vector("weights", weights)
# weights: [0.12, 0.47, 0.85, 0.33]
Format Specification Mini-Language
{[fill][align][sign][width][grouping][.precision][type]}
type codes:
d → integer {:d} → 42
f → fixed float {:.2f} → 3.14
e → scientific {:.2e} → 3.14e+00
% → percentage {:.1%} → 31.4%
s → string {:s} → hello
b → binary {:b} → 101010
x → hexadecimal {:x} → 2a
o → octal {:o} → 52
Examples:
"{:08b}".format(42) → "00101010"
"{:.2e}".format(12345) → "1.23e+04"
"{:.1%}".format(0.856) → "85.6%"
Key Takeaways
Simple string concatenation with + and String() handles short output. Python f-string format via py.str("{...}").format(...) handles complex templates with alignment, padding, and precision. Use :<, :>, and :^ for left, right, and center alignment in fixed-width columns. Use :.Nf for N decimal places and :, for thousands separators. Wrap repeated formatting patterns in a helper function to keep call sites clean. The Python format mini-language is available in full through Mojo's Python interop layer.
