Proper indentation for Python multiline strings
You probably want to line up with the
def foo(): string = """line one line two line three"""
Since the newlines and spaces are included in the string itself, you will have to postprocess it. If you don't want to do that and you have a whole lot of text, you might want to store it separately in a text file. If a text file does not work well for your application and you don't want to postprocess, I'd probably go with
def foo(): string = ("this is an " "implicitly joined " "string")
If you want to postprocess a multiline string to trim out the parts you don't need, you should consider the
textwrap module or the technique for postprocessing docstrings presented in PEP 257:
def trim(docstring): if not docstring: return '' # Convert tabs to spaces (following the normal Python rules) # and split into a list of lines: lines = docstring.expandtabs().splitlines() # Determine minimum indentation (first line doesn't count): indent = sys.maxint for line in lines[1:]: stripped = line.lstrip() if stripped: indent = min(indent, len(line) - len(stripped)) # Remove indentation (first line is special): trimmed = [lines.strip()] if indent < sys.maxint: for line in lines[1:]: trimmed.append(line[indent:].rstrip()) # Strip off trailing and leading blank lines: while trimmed and not trimmed[-1]: trimmed.pop() while trimmed and not trimmed: trimmed.pop(0) # Return a single string: return '\n'.join(trimmed)
textwrap.dedent function allows one to start with correct indentation in the source, and then strip it from the text before use.
The trade-off, as noted by some others, is that this is an extra function call on the literal; take this into account when deciding where to place these literals in your code.
import textwrapdef frobnicate(param): """ Frobnicate the scrognate param. The Weebly-Ruckford algorithm is employed to frobnicate the scrognate to within an inch of its life. """ prepare_the_comfy_chair(param) log_message = textwrap.dedent("""\ Prepare to frobnicate: Here it comes... Any moment now. And: Frobnicate!""") weebly(param, log_message) ruckford(param)
\ in the log message literal is to ensure that line break isn't in the literal; that way, the literal doesn't start with a blank line, and instead starts with the next full line.
The return value from
textwrap.dedent is the input string with all common leading whitespace indentation removed on each line of the string. So the above
log_message value will be:
Prepare to frobnicate:Here it comes... Any moment now.And: Frobnicate!
inspect.cleandoc like so:
def method(): string = inspect.cleandoc(""" line one line two line three""")
Relative indentation will be maintained as expected. As commented below, if you want to keep preceding empty lines, use
textwrap.dedent. However that also keeps the first line break.
Note: It's good practice to indent logical blocks of code under its related context to clarify the structure. E.g. the multi-line string belonging to the variable