Search code examples
pythonstringnestedcode-readabilitymultilinestring

Indentation when using multi-line strings


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?


Solution

  • 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.