Let's talk about how to create a multi-line string in Python without accidentally indenting the text within that string.
Here we have a function that prints out a copyright statement:
def copyright():
print("""\
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved."""
)
This function works, but the copyright statement that it prints out is indented:
>>> copyright()
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved.
Each line in this copyright statement begins with eight spaces. This happens because in our code, the text within our string begins with eight spaces before each line.
We can fix this problem by manually dedenting the text within this string:
def copyright():
print("""\
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved."""
)
While this does work:
>>> copyright()
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved.
This also makes our code a bit tricky to read.
Our code is less readable than before because up here, we our code suddenly dedents in the middle of our string.
We could fix this problem in by using the dedent function in Python's textwrap module.
textwrap.dedent to unindent stringsThe dedent function allows us to indent our code however we'd like.
Our multi-line string can be nicely indented in our code because the dedent function will will dedent it for us:
from textwrap import dedent
def copyright():
print(dedent("""\
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved."""
))
At the point where we use this string, we'll see that it doesn't have any indentation:
>>> copyright()
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved.
The dedent function removed the indentation for us.
Note that our string starts with a backslash (\):
from textwrap import dedent
def copyright():
print(dedent("""\
...
))
That backslash removes the extra newline character (\n) that this string would start with if this backslash weren't here.
Without that backslash, we would need to start our text on the same line to avoid that newline character:
from textwrap import dedent
def copyright():
print(dedent("""Copyright (c) 1991-2000 ACME Corp
...
Note that we're also ending our multi-line string on the same line that our text ends:
from textwrap import dedent
def copyright():
print(dedent("""\
...
All Rights Reserved."""
))
It would be nice if we could end it on the next line instead, but that would add an extra newline at the end of our string.
I prefer to combine dedent with the string strip method to take care of these newlines.
dedent with strip to make the code more readableHere we're using the strip method with our string:
from textwrap import dedent
def copyright():
print(dedent("""
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved.
""").strip("\n"))
The dedent function is dedenting a string that starts with a newline character and ends with a newline character (note that we end our multi-line string on the next line).
After we dedent, we then use the string strip method to remove those newline characters.
Our copyright statement looks as it should:
>>> copyright()
Copyright (c) 1991-2000 ACME Corp
All Rights Reserved.
Copyright (c) 2000-2030 Cyberdyne
All Rights Reserved.
And we have nicely indented code that doesn't have a strange backslash. Plus we don't need to worry about where exactly our multi-line string ends in our code: we're ending our string on the new line and that's okay!
dedent maintains relative indentation levelsIt's important to note that the dedent function doesn't remove all whitespace from the beginning of each line.
It's a little bit smarter than that.
The dedent function maintains relative indentation within a string.
Here we have a string that is expected to have some lines indented more than others:
from textwrap import dedent
example_list = dedent("""
- Fix leap year bug
- User registration breaks on leap years
- Write a regression test
- Record a screencast
""").strip("\n")
print("The list.txt file should show a bulleted list, like this:")
print(example_list)
You can see that every line has at least four spaces of indentation, but some lines have more indentation.
When we run dedent against this string, you'll see the four spaces of indentation (that's common to each line) is removed:
$ python3 example_list.py
The list.txt file should show a bulleted list, like this:
- Fix leap year bug
- User registration breaks on leap years
- Write a regression test
- Record a screencast
But the indentation that some lines have (that is relatively greater than other lines) is maintained.
textwrap.dedent to unindent stringsIf you'd like to nicely format your multi-line string within your Python code without printing indented text by mistake, you can use the dedent function from Python's textwrap module.
We don't learn by reading or watching. We learn by doing. That means writing Python code.
Practice this topic by working on these related Python exercises.
Need to fill-in gaps in your Python skills? I send weekly emails designed to do just that.
Sign in to your Python Morsels account to track your progress.
Don't have an account yet? Sign up here.