Python
Multiline String
Inline Variables
String Formatting
Python Programming

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

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

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

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.