195

I am looking for a clean way to use variables within a multiline Python string. Say I wanted to do the following:

string1 = go
string2 = now
string3 = great

"""
I will $string1 there
I will go $string2
$string3
"""

I'm looking to see if there is something similar to $ in Perl to indicate a variable in the Python syntax.

If not - what is the cleanest way to create a multiline string with variables?

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
evolution
  • 4,332
  • 5
  • 29
  • 34

9 Answers9

249

The common way is the format() function:

>>> s = "This is an {example} with {vars}".format(vars="variables", example="example")
>>> s
'This is an example with variables'

It works fine with a multi-line format string:

>>> s = '''\
... This is a {length} example.
... Here is a {ordinal} line.\
... '''.format(length='multi-line', ordinal='second')
>>> print(s)
This is a multi-line example.
Here is a second line.

You can also pass a dictionary with variables:

>>> d = { 'vars': "variables", 'example': "example" }
>>> s = "This is an {example} with {vars}"
>>> s.format(**d)
'This is an example with variables'

The closest thing to what you asked (in terms of syntax) are template strings. For example:

>>> from string import Template
>>> t = Template("This is an $example with $vars")
>>> t.substitute({ 'example': "example", 'vars': "variables"})
'This is an example with variables'

I should add though that the format() function is more common because it's readily available and it does not require an import line.

user2357112
  • 260,549
  • 28
  • 431
  • 505
Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
  • 2
    Could use `vars()` or `locals()` as the dictionary in question – Ismail Badawi Apr 11 '12 at 19:34
  • 2
    @isbadawi Explicit is better than implicit. Better to pass in only the variables you need. If you don't know which you need, because the string is supplied by the user, the "variables" should be items in a `dict` anyway. – agf Apr 11 '12 at 19:35
  • The second solution is cleanest IMO. The dictionary along with clear variable name from the dictionary within the multiline sting. I will be using this method. Thanks. Loads of great answers below too but this was perfect. – evolution Apr 12 '12 at 00:39
  • @SimeonVisser, "string".format(...) is not valid on legacy python versions (e.g. 2.4) – oz123 Nov 16 '12 at 10:12
  • 5
    If using curly braces, they need to be escaped like `{{this}}`. – Jonny Jul 24 '18 at 02:03
  • i'm trying to substitue value of Y in below codeusing format function raw_data ="""query getSpace { space(id: {y}) { title description membersUpdated members { items { email displayName } } conversation{ messages{ items { content } } } } }""".format(y='5bfe4e1e653c890001871844') But i'm getting Error: Please help – Rohit Nov 29 '18 at 07:18
  • The `'''string here'''` technique is a solid technique, and works well, but it creates some REALLY UGLY source code when you have to left-align all but the first line and your source code is indented several levels. To get pretty and easy-to-look-at source code with nice alignment, therefore, use this technique here instead: https://stackoverflow.com/a/54564926/4561887. It has its drawbacks, of course, but for anything less than a long paragraph of text, I like this other technique over using the `''' '''` technique. – Gabriel Staples Feb 07 '19 at 01:26
69

NOTE: The recommended way to do string formatting in Python is to use format(), as outlined in the accepted answer. I'm preserving this answer as an example of the C-style syntax that's also supported.

# NOTE: format() is a better choice!
string1 = "go"
string2 = "now"
string3 = "great"

s = """
I will %s there
I will go %s
%s
""" % (string1, string2, string3)

print(s)

Some reading:

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
David Cain
  • 16,484
  • 14
  • 65
  • 75
  • 2
    This isn't really the same because the OP wants named parameters, not positional ones. – Ismail Badawi Apr 11 '12 at 19:33
  • 2
    It's still a good solution, and for a multi-line interpolation it's more direct. You don't have to import anything and it uses regular python interpolation. – unflores Dec 23 '14 at 10:52
  • 9
    "*You probably could have answered this one with a little bit of Googling*" Implying that we didn't find this post after Googling... – Stevoisiak Oct 30 '17 at 19:37
69

You can use Python 3.6's f-strings for variables inside multi-line or lengthy single-line strings. You can manually specify newline characters using \n.

Variables in a multi-line string

string1 = "go"
string2 = "now"
string3 = "great"

multiline_string = (f"I will {string1} there\n"
                    f"I will go {string2}.\n"
                    f"{string3}.")

print(multiline_string)

I will go there
I will go now
great

Variables in a lengthy single-line string

string1 = "go"
string2 = "now"
string3 = "great"

singleline_string = (f"I will {string1} there. "
                     f"I will go {string2}. "
                     f"{string3}.")

print(singleline_string)

I will go there. I will go now. great.


Alternatively, you can also create a multiline f-string with triple quotes.

multiline_string = f"""I will {string1} there.
I will go {string2}.
{string3}."""
Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
  • This keeps your source code looking pretty, and in pre-Python3.6 you can get the same effect just by doing this (extra set of parenthesis and using `+` to concatenate): https://stackoverflow.com/a/54564926/4561887 – Gabriel Staples Feb 07 '19 at 01:23
  • 14
    Triple quoting is *vastly* preferred. You should present that form first. – jpmc26 Jul 15 '19 at 18:53
  • 1
    @jpmc26 I presented parenthesis-style first based on [PEP 8's guidelines for code indentation](https://www.python.org/dev/peps/pep-0008/#indentation). Why would triple quoting be preferred? – Stevoisiak Jul 15 '19 at 19:04
  • I always forget about the `f` prefix to enable formatting inline. But I like this approach for multi-inline formatting. – Maxs728 May 03 '21 at 09:04
27

f-strings, also called “formatted string literals,” are string literals that have an f at the beginning; and curly braces containing expressions that will be replaced with their values.

f-strings are evaluated at runtime.

So your code can be re-written as:

string1="go"
string2="now"
string3="great"
print(f"""
I will {string1} there
I will go {string2}
{string3}
""")

And this will evaluate to:

I will go there
I will go now
great

You can learn more about it here.

Anshika Singh
  • 994
  • 12
  • 20
13

This is what you want:

>>> string1 = "go"
>>> string2 = "now"
>>> string3 = "great"
>>> mystring = """
... I will {string1} there
... I will go {string2}
... {string3}
... """
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, 'string3': 'great', '__package__': None, 'mystring': "\nI will {string1} there\nI will go {string2}\n{string3}\n", '__name__': '__main__', 'string2': 'now', '__doc__': None, 'string1': 'go'}
>>> print(mystring.format(**locals()))

I will go there
I will go now
great
Havok
  • 5,776
  • 1
  • 35
  • 44
  • Note that triple quotes `"""` preserves newlines, which means there is an extra newline before and after `mystring` – Stevoisiak Oct 30 '17 at 20:44
  • You can use ``.strip()``, ``.rstrip()`` or ``.lstrip()``, or ue a backlash inside the triple quotes to avoid creating a newline. mystring = """\ ABC\ """ – Havok Nov 02 '17 at 22:55
13

If anyone came here from python-graphql client looking for a solution to pass an object as variable here's what I used:

query = """
{{
  pairs(block: {block} first: 200, orderBy: trackedReserveETH, orderDirection: desc) {{
    id
    txCount
    reserveUSD
    trackedReserveETH
    volumeUSD
  }}
}}
""".format(block=''.join(['{number: ', str(block), '}']))

 query = gql(query)

Make sure to escape all curly braces like I did: "{{", "}}"

Radu Ciobanu
  • 710
  • 8
  • 10
  • Useful example for GraphQL highlighting how to escape braces. For simpler interpolation, query = f""" {{ pairs( block: {block_value} ...) {{ ... }} }} """ also works. – Dan Dascalescu Mar 08 '23 at 12:10
8

A dictionary can be passed to format(), each key name will become a variable for each associated value.

dict = {'string1': 'go',
        'string2': 'now',
        'string3': 'great'}

multiline_string = '''I'm will {string1} there
I will go {string2}
{string3}'''.format(**dict)

print(multiline_string)


Also a list can be passed to format(), the index number of each value will be used as variables in this case.

list = ['go',
        'now',
        'great']

multiline_string = '''I'm will {0} there
I will go {1}
{2}'''.format(*list)

print(multiline_string)


Both solutions above will output the same:

I'm will go there
I will go now
great

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
jesterjunk
  • 2,342
  • 22
  • 18
2
print (f" \
      What you want to write {var_one} \n \
      What you want to write {var_two} \n \
      What you want to write {var_three} \n \
      Et cetera {var_four}")

This was what was working for me. Maybe it helps someone, cheers

sivi
  • 10,654
  • 2
  • 52
  • 51
1

Simplest way is to use f-string multiline.

string1 = "go"
string2 = "now"
string3 = "great"

s = f"""
I will {string1} there
I will go {string2}
{string3}
"""

print(s)

This will return.

I will go there
I will go now
great

Hope this helps.

KnowledgeSeeeker
  • 620
  • 1
  • 9
  • 14