Python
Multiline String
Inline Variables
String Formatting
Python Programming

How do I create a multiline Python string with inline variables?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Python offers several ways to create multiline strings with embedded variables. The most modern and readable approach is f-strings with triple quotes (f"""..."""), available since Python 3.6. Older alternatives include str.format() with triple-quoted strings and the % operator. Each method handles multiline text and variable interpolation, but they differ in readability, safety, and flexibility. For most use cases, f-strings are the best choice.

python
1name = "Alice"
2age = 30
3city = "New York"
4
5message = f"""
6Dear {name},
7
8Your profile has been updated:
9  - Age: {age}
10  - City: {city}
11  - Status: {'Active' if age >= 18 else 'Minor'}
12
13Thank you for using our service.
14"""
15
16print(message)

F-strings evaluate expressions inside {} at runtime. Triple quotes (""" or ''') allow the string to span multiple lines. You can include any Python expression inside the braces — function calls, conditionals, arithmetic, and method calls.

str.format() with Triple Quotes

python
1template = """
2Hello {name},
3
4Your order #{order_id} has been shipped.
5Estimated delivery: {days} business days.
6
7Tracking: {tracking}
8"""
9
10message = template.format(
11    name="Bob",
12    order_id=12345,
13    days=3,
14    tracking="1Z999AA10123456784"
15)
16
17print(message)

str.format() separates the template from the data, making it useful when the template is defined separately from where it is populated — for example, in a configuration file or a different module.

Percent (%) Formatting

python
1name = "Carol"
2items = 5
3total = 49.99
4
5message = """
6Customer: %s
7Items purchased: %d
8Total: $%.2f
9
10Thank you for shopping with us.
11""" % (name, items, total)
12
13print(message)

% formatting is the oldest string interpolation method in Python. It works but is less readable than f-strings, especially with many variables. It uses C-style format specifiers (%s, %d, %f).

textwrap.dedent for Clean Indentation

python
1from textwrap import dedent
2
3def generate_email(user, product):
4    return dedent(f"""\
5        Hi {user},
6
7        Your purchase of {product} is confirmed.
8        You will receive a confirmation email shortly.
9
10        Best regards,
11        Support Team
12    """)
13
14print(generate_email("Dave", "Widget Pro"))

When multiline strings are inside indented functions, textwrap.dedent() removes the common leading whitespace so the output is not indented. The \ after the opening """ prevents a leading blank line.

Template Strings (Safe for User Input)

python
1from string import Template
2
3# Template uses $variable syntax
4template = Template("""
5Hello $name,
6
7Your account balance is $$${balance}.
8Your account ID: $account_id
9""")
10
11result = template.substitute(
12    name="Eve",
13    balance="1,250.00",
14    account_id="ACC-001"
15)
16print(result)
17
18# safe_substitute ignores missing variables instead of raising
19partial = template.safe_substitute(name="Eve")
20print(partial)  # $balance and $account_id remain as-is

Template strings are safer for user-provided templates because they do not execute arbitrary Python expressions. $$ produces a literal $ sign. Use safe_substitute() when not all variables may be available.

Joining Lines

python
1name = "Frank"
2items = ["Widget", "Gadget", "Tool"]
3
4# Build multiline string from parts
5lines = [
6    f"Order for {name}:",
7    "",
8    "Items:",
9]
10lines.extend(f"  - {item}" for item in items)
11lines.append(f"\nTotal items: {len(items)}")
12
13message = "\n".join(lines)
14print(message)

For dynamic content where the number of lines varies, building a list and joining with "\n" is cleaner than concatenating strings or using multiple f-string lines.

Multiline Strings in Function Arguments

python
1import logging
2
3name = "Grace"
4error_code = 500
5
6# f-string in a function call
7logging.error(
8    f"Request failed for user {name}.\n"
9    f"Error code: {error_code}.\n"
10    f"Please retry or contact support."
11)
12
13# Implicit string concatenation (adjacent string literals)
14query = (
15    f"SELECT * FROM users "
16    f"WHERE name = '{name}' "
17    f"AND status = 'active'"
18)

Python automatically concatenates adjacent string literals. Wrapping in parentheses creates a multiline expression without actually embedding newlines — useful for SQL queries or log messages that should be a single line.

Raw Strings with Variables

python
1path = "users"
2pattern = rf"""
3    ^/{path}/
4    (?P<user_id>\d+)/
5    profile$
6"""
7
8import re
9regex = re.compile(pattern, re.VERBOSE)
10print(regex.match("/users/123/profile"))

The rf"""...""" prefix combines raw strings (no backslash escaping) with f-string interpolation. This is useful for regex patterns where you need both literal backslashes and variable substitution.

Common Pitfalls

  • Unintended leading whitespace: Triple-quoted strings inside indented code include the indentation in the string. Use textwrap.dedent() to strip it, or use parenthesized string concatenation instead.
  • Curly braces in f-strings: To include a literal { or } in an f-string, double it: f"dict = {{'key': {value}}}". A single { without a variable inside raises SyntaxError.
  • Security with f-strings and user input: Never use f-strings to build SQL queries, shell commands, or HTML with user-provided data. Use parameterized queries, shlex.quote(), or template engines instead.
  • Leading newline with triple quotes: """\\ntext""" has a blank first line. Use """\\ (backslash immediately after quotes) or textwrap.dedent to avoid it.
  • Mixing format methods: Combining % and .format() in the same string causes TypeError or KeyError. Pick one method and use it consistently throughout each string.

Summary

  • Use f"""...""" (f-strings with triple quotes) for most multiline strings with variables
  • Use str.format() when templates are defined separately from data
  • Use textwrap.dedent() to remove leading whitespace from indented multiline strings
  • Use string.Template for user-provided templates where arbitrary code execution is a risk
  • Use parenthesized string concatenation for single-line strings split across multiple code lines
  • Never use f-strings to interpolate user input into SQL, shell commands, or HTML

Course illustration
Course illustration

All Rights Reserved.