PEP 498 in 90 seconds — f-strings and the death of "Hello %s"
Inline expressions in strings — finally.
Pre-3.6, formatting a string meant `%` formatting, `.format()`, or naked concatenation: ```python # All three work, none read well. "Hello %s, you are %d" % (name, age) "Hello {}, you are {}".format(name, age) "Hello " + name + ", you are " + str(age) ``` The reader (you, six months later) had to mentally pair each placeholder with the right argument. PEP 498 inlined the expression where it appears.
f-strings put the expression inside `{...}` directly: ```python f"Hello {name}, you are {age}" ``` It's not just shorter — `{expr}` runs `expr` at runtime and inserts the result. Any expression works: function calls, arithmetic, attribute access. They're also the **fastest** formatting option (no `.format()` parsing overhead) and got first-class debug syntax in 3.8: `f"{value=}"` prints `value=<repr>`.
name = "Anna"
age = 30
# % style — positional, fragile if you add a field
"Hello %s, you are %d" % (name, age)
# .format() — verbose, parsing overhead
"Hello {}, you are {}".format(name, age)
# concat — only works for strings; everything else needs str()
"Hello " + name + ", you are " + str(age)name = "Anna"
age = 30
# Single line, reads left-to-right
greeting = f"Hello {name}, you are {age}"
# Any expression works:
print(f"Next year: {age + 1}")
print(f"Name uppercase: {name.upper()}")
print(f"Two pi: {3.14 * 2:.4f}") # format spec after :
print(f"{name=}") # debug syntax (3.8+)🎯 Predict the output
What does this print? (Format specs: `:.2f` = 2 decimals, `:=^20` = center-align in 20-char field, padded with `=`.)
price = 42.157
items = ["pen", "pad", "ink"]
print(f"${price:.2f}")
print(f"{len(items)} items: {', '.join(items)}")
print(f"{'banner':=^20}")