Skip to Content

Strings & f-strings

When to use

Compose, format, interpolate, or inspect text.

Analogy

An f-string is a fill-in-the-blanks form whose blanks are evaluated now and frozen into a real string.

Data-flow diagram

template: f'Hello {name}, {bal:.2f}'
   |
   | eval each {expr} at runtime
   v
result: 'Hello Ada, 12.50'

Deep explanation

Strings are immutable sequences of Unicode code points. f-strings (PEP 498) compile and evaluate any {expr} at runtime - the fastest of the formatting family. Format specs: .2f, >10, ^, !r. The 3.8+ = self-doc form f'{x=}' shows name=value. f-strings are NOT a safener; never interpolate user input into SQL or HTML.

Examples

Example 1

name = 'Ada'
print(f'Hello {name}!')
print(f'{name=}')

positional interpolation + the = self-doc form for quick debugging.

Example 2

pi = 3.14159
print(f'{pi:.2f}')     # '3.14'
print(f'{pi:>10.4f}')  # right-aligned

format specs control width, alignment, fill, and precision.

Example 3

# opposite quote wrapper to avoid escaping
print(f"{data['name']} is {data['age']}")

wrap f-string in opposite quotes to keep inner quotes unescaped.

Common mistake

Treating f-strings as SQL/HTML safeners. f-strings do NOT escape - interpolating user input via f-string into a SQL query is the canonical SQLi vector. Use parameterised queries; use Jinja2 autoescape for HTML.

Key takeaway

f-strings: fast, in-source, evaluated now. Use for logs/UI. NEVER for SQL/HTML/JS with user input. Reach for = debug form when poking.

Production Failure Playbook

Failure scenario 1: xss-via-f-string-into-html

Failure scenario 2: sql-injection-via-f-string