How do I wrap long lines in Python without sacrificing indentation?
For example:
def fun():
print '{0} Here is a really long sentence with {1}'.format(3, 5)
Suppose this goes over the 79 character recommended limit. The way I read it, here is how to indent it:
def fun():
print '{0} Here is a really long \
sentence with {1}'.format(3, 5)
However, with this approach, the indentation of the continued line matches the indentation of the fun()
. This looks kinda ugly. If someone was to go through my code, it would look bad to have uneven indentation because of this print
statement.
How do I indent lines like this effectively without sacrificing code readability?
def fun():
print(('{0} Here is a really long '
'sentence with {1}').format(3, 5))
Adjacent string literals are concatenated at compile time, just as in C. http://docs.python.org/reference/lexical_analysis.html#string-literal-concatenation is a good place to start for more info.
Using concatenation of adjacent string literals, together with formatted string literals is the way to go:
x = 2
sep = 2 * '\n'
print(
'This message is so long that it requires '
f'more than {x} lines.{sep}'
'And more lines may be needed.')
This approach complies with PEP 8 and allows better use of space.
No +
operators needed, no backslashes for line continuation, no irregularities of indentation, no error-prone +=
to an accumulator string variable (which can be mistyped as =
, resulting in a silent error), no stray parenthesis hanging below the print
(the arguments are placed in their own level of indentation, and the next element at the indentation level of print
is the next statement).
Starting the strings on the line below the line that contains the print(
reduces indentation, and is more readable. Readability stems from both print(
standing out, by being on its own line, and by the uniform alignment of consecutive statements of this form.
The reduction in indentation from this approach becomes more evident when raising exceptions:
raise ModuleNotFoundError(
'aaaaaaaaaaaaaaaaaaaaaaaa'
'aaaaaaaaaaaaaaaaaaaaaaaa'
f'aaaaa {x} aaaaa')
Regarding formatted string literals (signified by the prefix "f", as in f'...'
), raw strings can be formatted string literals, by combining the prefixes "r" and "f":
rf'This is a formatted raw string, {sep}here is a backslash \.'
Note that raw strings are necessary for including literal backslashes without writing \\
. Otherwise, in a future CPython version, a SyntaxError
will be raised. As of Python 3.9, a DeprecationWarning
is raised:
python -X dev -c '"\q"'
outputs:
<string>:1: DeprecationWarning: invalid escape sequence \q
The replacements are very readable. In particular, this approach makes writing code that generates code or mathematical formulas a very pleasant task.
Rarely, the method str.format
may be suitable, due to what substitutions are needed. It can be used as follows:
print((
'This message is so long that it requires '
'more than {x} lines.{sep}'
'And more lines may be needed.'
).format(x=x, sep=sep))
You could use the following code where indentation doesn't matter:
>>> def fun():
return ('{0} Here is a really long'
' sentence with {1}').format(3, 5)
You just need to enclose string in the parentheses.
You can use the fact that Python concatenates string literals which appear adjacent to each other:
>>> def fun():
... print '{0} Here is a really long ' \
... 'sentence with {1}'.format(3, 5)
I'd probably split the long statement up into multiple shorter statements so that the program logic is separated from the definition of the long string:
>>> def fun():
... format_string = '{0} Here is a really long ' \
... 'sentence with {1}'
... print format_string.format(3, 5)
If the string is only just too long and you choose a short variable name then by doing this you might even avoid having to split the string:
>>> def fun():
... s = '{0} Here is a really long sentence with {1}'
... print s.format(3, 5)
I'm surprised no one mentioned the implicit style above. My preference is to use parens to wrap the string while lining the string lines up visually. Personally I think this looks cleaner and more compact than starting the beginning of the string on a tabbed new line.
Note that these parens are not part of a method call — they're only implicit string literal concatenation.
Python 2:
def fun():
print ('{0} Here is a really '
'long sentence with {1}').format(3, 5)
Python 3 (with parens for print function):
def fun():
print(('{0} Here is a really '
'long sentence with {1}').format(3, 5))
Personally I think it's cleanest to separate concatenating the long string literal from printing it:
def fun():
s = ('{0} Here is a really '
'long sentence with {1}').format(3, 5)
print(s)
精彩评论