Skip to main content

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

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
tip

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}
warning

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:

  1. Use Implicit Concatenation ((f"..." f"...")) when you want precise control over the output format while keeping your code indentation clean. This requires manual \n characters.
  2. Use Triple Quotes with textwrap.dedent when generating large blocks of text (like emails or documentation) where preserving the visual structure in code is prioritized.
  3. Check prefixes: Ensure every line in a concatenated block has an f if it contains variables.