How to Format Multiline Strings Correctly in Python f-strings
Introduced in Python 3.6, f-strings provide a concise way to embed expressions inside string literals. However, handling strings that span multiple lines often leads to issues with unwanted indentation, syntax errors regarding newlines, or readability problems.
This guide explains the standard methods for creating multiline f-strings using triple quotes and implicit concatenation, and how to resolve common whitespace issues using textwrap.
Method 1: Triple Quotes (Preserves Newlines)
The most direct way to create a multiline f-string is using triple quotes (f"""...""" or f'''...'''). This captures everything inside the quotes, including newlines and indentation.
The Indentation Problem
While this method is simple, it often breaks the visual structure of your code output because the indentation used to align the code is treated as part of the string.
name = "Alice"
score = 95
def print_report():
# ⛔️ Problem: Code indentation is captured in the string
report = f"""
User: {name}
Score: {score}
"""
print(report)
print_report()
Output:
User: Alice
Score: 95
Note the unwanted empty lines and leading spaces.
Method 2: Implicit Concatenation (Best for Indentation)
To keep your code indented cleanly without injecting spaces into the final string, use implicit string concatenation. You wrap the string in parentheses () and place each line on a new row.
You must attach the f prefix to every line that contains variables.
name = "Alice"
score = 95
# ✅ Correct: Parentheses allow line breaks without adding 'real' newlines
# Note: You must add \n manually if you actually want line breaks in the output
message = (
f"User: {name}\n"
f"Score: {score}\n"
"Status: Active" # No 'f' needed if no variables here
)
print(message)
Output:
User: Alice
Score: 95
Status: Active
This approach is preferred for long SQL queries or log messages where you want the code to look aligned, but the output string should not contain the code's indentation.
Method 3: Using textwrap.dedent (Cleaning Whitespace)
If you prefer the readability of triple quotes but want to remove the unwanted indentation shown in Method 1, use the standard library textwrap.dedent.
This allows you to write the string indented relative to the function, but strips that common leading whitespace at runtime.
import textwrap
name = "Alice"
score = 95
def print_clean_report():
# ✅ Correct: Triple quotes for ease, dedent for cleanup
# The backslash \ at the start prevents an initial empty line
report = textwrap.dedent(f"""\
User: {name}
Score: {score}
""")
print(report)
print_clean_report()
Output:
User: Alice
Score: 95
Common Pitfall: Missing f-Prefixes
When using implicit concatenation (Method 2), a very common bug is forgetting the f prefix on subsequent lines. Python will treat the line as a standard string and print the curly braces literally.
name = "Alice"
age = 30
# ⛔️ Incorrect: Second line is missing 'f'
message = (
f"Name: {name}\n"
"Age: {age}"
)
print(message)
Output:
Name: Alice
Age: {age}
Prior to Python 3.12, you could not use backslashes \ inside the expression part {} of an f-string. While Python 3.12+ supports it, it is best practice to perform complex logic or multiline calculations outside the f-string for readability.
Conclusion
To format multiline f-strings effectively:
- Use Implicit Concatenation (
(f"..." f"...")) when you want precise control over the output format while keeping your code indentation clean. This requires manual\ncharacters. - Use Triple Quotes with
textwrap.dedentwhen generating large blocks of text (like emails or documentation) where preserving the visual structure in code is prioritized. - Check prefixes: Ensure every line in a concatenated block has an
fif it contains variables.