Pythonic way to create a long multi-line string

Posted on

Solving problem is about exposing yourself to as many situations as possible like Pythonic way to create a long multi-line string and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about Pythonic way to create a long multi-line string, which can be followed any time. Take easy to follow this discuss.

Pythonic way to create a long multi-line string

I have a very long query. I would like to split it in several lines in Python. A way to do it in JavaScript would be using several sentences and joining them with a + operator (I know, maybe it’s not the most efficient way to do it, but I’m not really concerned about performance in this stage, just code readability). Example:

var long_string = 'some text not important. just garbage to' +
                  'illustrate my example';

I tried doing something similar in Python, but it didn’t work, so I used to split the long string. However, I’m not sure if this is the only/best/pythonicest way of doing it. It looks awkward.
Actual code:

query = 'SELECT action.descr as "action", '
    'role.id as role_id,'
    'role.descr as role'
    'FROM '
    'public.role_action_def,'
    'public.role,'
    'public.record_def, '
    'public.action'
    'WHERE role.id = role_action_def.role_id AND'
    'record_def.id = role_action_def.def_id AND'
    'action.id = role_action_def.action_id AND'
    'role_action_def.account_id = ' + account_id + ' AND'
    'record_def.account_id=' + account_id + ' AND'
    'def_id=' + def_id

Answer #1:

Are you talking about multi-line strings? Easy, use triple quotes to start and end them.

s = """ this is a very
        long string if I had the
        energy to type more and more ..."""

You can use single quotes too (3 of them of course at start and end) and treat the resulting string s just like any other string.

NOTE: Just as with any string, anything between the starting and ending quotes becomes part of the string, so this example has a leading blank (as pointed out by @root45). This string will also contain both blanks and newlines.

I.e.,:

' this is a veryn        long string if I had then        energy to type more and more ...'

Finally, one can also construct long lines in Python like this:

 s = ("this is a very"
      "long string too"
      "for sure ..."
     )

which will not include any extra blanks or newlines (this is a deliberate example showing what the effect of skipping blanks will result in):

'this is a verylong string toofor sure ...'

No commas required, simply place the strings to be joined together into a pair of parenthesis and be sure to account for any needed blanks and newlines.

Answered By: Levon

Answer #2:

If you don’t want a multiline string but just have a long single line string, you can use parentheses, just make sure you don’t include commas between the string segments, then it will be a tuple.

query = ('SELECT   action.descr as "action", '
         'role.id as role_id,'
         'role.descr as role'
         ' FROM '
         'public.role_action_def,'
         'public.role,'
         'public.record_def, '
         'public.action'
         ' WHERE role.id = role_action_def.role_id AND'
         ' record_def.id = role_action_def.def_id AND'
         ' action.id = role_action_def.action_id AND'
         ' role_action_def.account_id = '+account_id+' AND'
         ' record_def.account_id='+account_id+' AND'
         ' def_id='+def_id)

In a SQL statement like what you’re constructing, multiline strings would also be fine. But if the extra whitespace a multiline string would contain would be a problem, then this would be a good way to achieve what you want.

Answered By: Jesse

Answer #3:

Breaking lines by works for me. Here is an example:

longStr = "This is a very long string "
        "that I wrote to help somebody "
        "who had a question about "
        "writing long strings in Python"
Answered By: amphibient

Answer #4:

I found myself happy with this one:

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('n',' ')
Answered By: Eero Aaltonen

Answer #5:

I find that when building long strings, you are usually doing something like building an SQL query, in which case this is best:

query = ' '.join((  # note double parens, join() takes an iterable
    "SELECT foo",
    "FROM bar",
    "WHERE baz",
))

What Levon suggested is good, but might be vulnerable to mistakes:

query = (
    "SELECT foo"
    "FROM bar"
    "WHERE baz"
)
query == "SELECT fooFROM barWHERE baz"  # probably not what you want
Answered By: darkfeline

Answer #6:

This approach uses:

  • just one backslash to avoid an initial linefeed
  • almost no internal punctuation by using a triple quoted string
  • strips away local indentation using the textwrap inspect module
  • uses python 3.6 formatted string interpolation (‘f’) for the account_id and def_id variables.

This way looks the most pythonic to me.

# import textwrap  # See update to answer below
import inspect
# query = textwrap.dedent(f'''
query = inspect.cleandoc(f'''
    SELECT action.descr as "action",
    role.id as role_id,
    role.descr as role
    FROM
    public.role_action_def,
    public.role,
    public.record_def,
    public.action
    WHERE role.id = role_action_def.role_id AND
    record_def.id = role_action_def.def_id AND
    action.id = role_action_def.action_id AND
    role_action_def.account_id = {account_id} AND
    record_def.account_id={account_id} AND
    def_id={def_id}'''
)

Update: 1/29/2019 Incorporate @ShadowRanger’s suggestion to use inspect.cleandoc instead of textwrap.dedent

Answered By: Christopher Bruns

Answer #7:

You can also concatenate variables in when using “”” notation:

foo = '1234'
long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ +  foo + """ aks
asdkfkasdk fak"""

EDIT: Found a better way, with named params and .format():

body = """
<html>
<head>
</head>
<body>
    <p>Lorem ipsum.</p>
    <dl>
        <dt>Asdf:</dt>     <dd><a href="{link}">{name}</a></dd>
    </dl>
    </body>
</html>
""".format(
    link='http://www.asdf.com',
    name='Asdf',
)
print(body)
Answered By: gjgjgj

Answer #8:

In Python >= 3.6 you can use Formatted string literals (f string)

query= f'''SELECT   action.descr as "action"
    role.id as role_id,
    role.descr as role
    FROM
    public.role_action_def,
    public.role,
    public.record_def,
    public.action
    WHERE role.id = role_action_def.role_id AND
    record_def.id = role_action_def.def_id AND
    action.id = role_action_def.action_id AND
    role_action_def.account_id = {account_id} AND
    record_def.account_id = {account_id} AND
    def_id = {def_id}'''
Answered By: Vlad Bezden

Leave a Reply

Your email address will not be published.