2

I sometimes need to use multi-line strings, but in a nested block. This works, but the readability is really poor:

CONDITION1 = CONDITION2 = CONDITION3 = True

if CONDITION1:
    if CONDITION2:
        s = """jkljkj
dfkjslfds
sqjdlqkj"""
    elif CONDITION3:
        s = """azeazea
azeoiuaez
azeytzae
azetzae"""

Using:

if CONDITION1:
    if CONDITION2:
        s = """jkljkj
               dfkjslfds
               sqjdlqkj"""

(as suggested in Pythonic way to create a long multi-line string) is not an option because the string s would be:

jkljkj
               dfkjslfds
               sqjdlqkj

with unwanted left spaces.

Question: how to use multi-line strings in nested blocks with a good readability?

Basj
  • 41,386
  • 99
  • 383
  • 673

2 Answers2

8

Wrap the string in a call to inspect.cleandoc and it will clean it up the same way docstrings get cleaned up (removing leading and trailing whitespace, and any level of common indentation).

>>> import inspect
>>> s = """jkljkj
...        dfkjslfds
...        sqjdlqkj"""
...
>>> print(s)
jkljkj
       dfkjslfds
       sqjdlqkj
>>> s = inspect.cleandoc(s)
>>> print(s)
jkljkj
dfkjslfds
sqjdlqkj

textwrap.dedent is also an option, but it's uglier, as it requires you to put no text on the first line, and explicitly use a line continuation character to ensure every line (not just the second and onwards) has identical leading indentation:

>>> print(textwrap.dedent('''\
...                       The^backslash is a pain
...                       so I don't recommend this approach
...                       '''))
The^backslash is a pain
so I don't recommend this approach

Note that while code blocks on SO don't show it properly, dedent left the empty final line (from putting the closing ''' on a line by itself), where cleandoc would have removed it.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Thank you very much! For completeness, could you add the same example with `dedent`? (I can also edit myself if you're ok) – Basj Jan 29 '19 at 21:19
  • @Basj: Done. I think it's usually the inferior solution, so I didn't want to emphasize it, but it's occasionally useful. – ShadowRanger Jan 29 '19 at 21:24
  • Thanks! I accepted your answer. I think `dedent` might be useful when we actually want to keep a particular indentation but just remove the left spaces. Example: `print(textwrap.dedent(""" some indented python code here """))`. – Basj Jan 29 '19 at 21:27
  • @Basj: If it's just a single line, you'd just use `.lstrip()` for that (comments don't show newlines, so it's possible you intended to put newlines and I just can't see them). – ShadowRanger Feb 02 '23 at 18:02
1

Have you tried using '\'. For example:

if CONDITION1:

   if CONDITION2:

       s = "jkljkj "\
           "dfkjslfds "\
           "sqjdlqkj"
Shafa Haider
  • 413
  • 2
  • 5
  • 13
  • Thank you, but not an option either, because my multiline string is very long. I don't want to have to manually add `" ... "\` around each line. – Basj Jan 29 '19 at 21:11