226

As PEP8 suggests keeping below the 80 column rule for your python program, how can I abide to that with long strings, i.e.

s = "this is my really, really, really, really, really, really, really long string that I'd like to shorten."

How would I go about expanding this to the following line, i.e.

s = "this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten."
Braiam
  • 4,345
  • 11
  • 47
  • 69
Federer
  • 30,291
  • 37
  • 89
  • 120
  • 2
    s = "this is my "+"really, "*6+"really long string that I'd like to shorten." # Ouch ;-) – Klaws Oct 22 '20 at 11:51

12 Answers12

326

Also, because neighboring string constants are automatically concatenated, you can code it like this too:

s = ("this is my really, really, really, really, really, really, "  
     "really long string that I'd like to shorten.")

Note no plus sign, and I added the extra comma and space that follows the formatting of your example.

Personally I don't like the backslashes, and I recall reading somewhere that its use is actually deprecated in favor of this form which is more explicit. Remember "Explicit is better than implicit."

I consider the backslash to be less clear and less useful because this is actually escaping the newline character. It's not possible to put a line end comment after it if one should be necessary. It is possible to do this with concatenated string constants:

s = ("this is my really, really, really, really, really, really, " # comments ok
     "really long string that I'd like to shorten.")

I used a Google search of "python line length" which returns the PEP8 link as the first result, but also links to another good StackOverflow post on this topic: "Why should Python PEP-8 specify a maximum line length of 79 characters?"

Another good search phrase would be "python line continuation".

Community
  • 1
  • 1
Todd
  • 5,361
  • 2
  • 17
  • 18
  • 9
    +1: "Personally I don't like the backslashes, and I recall reading somewhere that its use is actually deprecated in favor of this form which is more explicit. Remember "Explicit is better than implicit."" – Alberto Megía Sep 19 '13 at 08:16
  • 14
    For everyone who gets a tuple and wonders why. Do not add commas to the end of the lines here, that will result in a tuple, not a string. ;) – bugmenot123 Sep 18 '15 at 13:00
  • 7
    Isn't adding the + character more explicit than the given example? I'd still consider this implicit. i.e. `"str1" + "str2"` rather than `"str1" "str2"` – user1318135 Oct 03 '17 at 20:50
  • 5
    I actually agree that the plus sign is more explicit, but it does a different thing. It turns the string into an expression to be evaluated, rather than specifying a single string constant in a number of pieces. I'm not certain but I think this is done during parsing whereas the expression needs to be executed later. The speed difference is probably negligible unless there are a huge number of them. But also aesthetically I prefer the automatic concatenation since it is one less cluttery character per line. – Todd Dec 12 '17 at 04:30
  • 5
    This syntax also keeps the possibility of applying string formatting like: ``('this is my really, really, really, really, really long {} ' 'that I'd really, really, really, like to {}').format(var1, var2))`` – Tim Feb 21 '18 at 09:19
  • 2
    A warning: if the multiline string is a multiline formatted string, with an "f" at the beginning, the "f" needs to appear on each line. – macetw Jul 01 '20 at 20:29
  • True, the "f" needs to appear on each section that contains a replaceable part. – Todd Sep 05 '20 at 15:46
132

Implicit concatenation might be the cleanest solution:

s = "this is my really, really, really, really, really, really," \
    " really long string that I'd like to shorten."

Edit On reflection I agree that Todd's suggestion to use brackets rather than line continuation is better for all the reasons he gives. The only hesitation I have is that it's relatively easy to confuse bracketed strings with tuples.

Michael Dunn
  • 7,094
  • 4
  • 34
  • 50
  • 4
    This is why I felt like an idiot posting the question. Cheers. – Federer Dec 09 '09 at 15:33
  • 9
    This is line continuation by escaping the endline, not merely implicit concatenation, and until very recently explicitly forbidden in PEP8, although now there is an allowance, but NOT for long strings. Todd's answer below is correct. – Aaron Hall Dec 12 '13 at 22:16
  • 4
    I like PEP8, but this is part of PEP8 that I don't like. I feel like the implicit continuation is clearer, because of the possibility for confusion with tuples – monknomo Sep 20 '16 at 18:31
  • 1
    Remember not to add any blank spaces after \ – Mrinal Saurabh Jun 21 '19 at 06:11
16

I think the most important word in your question was "suggests".

Coding standards are funny things. Often the guidance they provide has a really good basis when it was written (e.g. most terminals being unable to show > 80 characters on a line), but over time they become functionally obsolete, but still rigidly adhered to. I guess what you need to do here is weigh up the relative merits of "breaking" that particular suggestion against the readability and mainatinability of your code.

Sorry this doesn't directly answer your question.

ZombieSheep
  • 28,629
  • 10
  • 64
  • 112
  • I totally agree. There is a similar Java style rule that has become obsolete too (IMHO). – Iker Jimenez Dec 09 '09 at 15:26
  • Yes I agree, however It's been racking my head how I would abide to it in this particular example. I always try to keep classes, methods to < 80 characters, however I'd say a string like this has no effect other than perhaps a negative one. – Federer Dec 09 '09 at 15:30
  • 1
    You also need to weigh your personal preference against the community-wide coding standard. You want new people to be able to come in and be comfortable with the code formatting from day one. – retracile Dec 09 '09 at 15:34
  • 2
    I know for my own self, I tend to stick to the 80 character limit just because I still do most of my coding in IDLE and I don't like the way it handles horizontal scrolling. (No scroll bar) – Tofystedeth Dec 09 '09 at 16:04
  • @retracile - yes, you do. I am not saying "You must ignore the guidance", rather suggesting that in some cases the guidance is not necessarily there for the good of the community. I wasn't aware of IDLE's restrictions (as posted by Tofystedeth) but in that instance there is a striong argument for following the convention. – ZombieSheep Dec 09 '09 at 16:30
  • I frequently use an editor/shell combo like Spyder on a split screen with a browser, so I don't know that it's entirely obsolete in terms of practicality (we now have night universal large screens, but that real estate can be valuable). – toonarmycaptain Jul 31 '17 at 03:30
14

You lost a space, and you probably need a line continuation character, ie. a \.

s = "this is my really, really, really, really, really, really" +  \
    " really long string that I'd like to shorten."

or even:

s = "this is my really, really, really, really, really, really"  \
    " really long string that I'd like to shorten."

Parens would also work instead of the line continuation, but you risk someone thinking you intended to have a tuple and had just forgotten a comma. Take for instance:

s = ("this is my really, really, really, really, really, really"
    " really long string that I'd like to shorten.")

versus:

s = ("this is my really, really, really, really, really, really",
    " really long string that I'd like to shorten.")

With Python's dynamic typing, the code may run either way, but produce incorrect results with the one you didn't intend.

retracile
  • 11,220
  • 2
  • 33
  • 42
3

Backslash:

s = "this is my really, really, really, really, really, really" +  \
    "really long string that I'd like to shorten."

or wrap in parens:

s = ("this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten.")
recursive
  • 77,417
  • 29
  • 137
  • 228
  • 2
    Note that the plus is necessary. Python concatenates string literals that follow each other. – bukzor Sep 23 '11 at 18:21
2

These are all great answers, but I couldn't find an editor plugin that would help me with editing "implicitly concatenated" strings, so I wrote a package to make it easier on me.

On pip (install paragraphs) if whoever's wandering this old thread would like to check it out. Formats multi-line strings the way html does (compress whitespace, two newlines for a new paragraph, no worries about spaces between lines).

from paragraphs import par


class SuddenDeathError(Exception):
    def __init__(self, cause: str) -> None:
        self.cause = cause

    def __str__(self):
        return par(
            f""" Y - e - e - e - es, Lord love you! Why should she die of
            {self.cause}? She come through diphtheria right enough the year
            before. I saw her with my own eyes. Fairly blue with it, she
            was. They all thought she was dead; but my father he kept ladling
            gin down her throat till she came to so sudden that she bit the bowl
            off the spoon. 

            What call would a woman with that strength in her have to die of
            {self.cause}? What become of her new straw hat that should have
            come to me? Somebody pinched it; and what I say is, them as pinched
            it done her in."""
        )


raise SuddenDeathError("influenza")

becomes ...

__main__.SuddenDeathError: Y - e - e - e - es, Lord love you! Why should she die of influenza? She come through diphtheria right enough the year before. I saw her with my own eyes. Fairly blue with it, she was. They all thought she was dead; but my father he kept ladling gin down her throat till she came to so sudden that she bit the bowl off the spoon.

What call would a woman with that strength in her have to die of influenza? What become of her new straw hat that should have come to me? Somebody pinched it; and what I say is, them as pinched it done her in.

Everything lines up easily with (Vim) 'gq'

Shay
  • 924
  • 7
  • 16
1

If you must insert a long string literal and want flake8 to shut up, you can use it's shutting up directives. For example, in a testing routine I defined some fake CSV input. I found that splitting it over more lines that it had rows would be mightily confusing, so I decided to add a # noqa: E501 as follows:

csv_test_content = """"STATION","DATE","SOURCE","LATITUDE","LONGITUDE","ELEVATION","NAME","REPORT_TYPE","CALL_SIGN","QUALITY_CONTROL","WND","CIG","VIS","TMP","DEW","SLP","AA1","AA2","AY1","AY2","GF1","MW1","REM"
"94733099999","2019-01-03T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","050,1,N,0010,1","22000,1,9,N","025000,1,9,9","+0260,1","+0210,1","99999,9","24,0000,9,1",,"0,1,02,1","0,1,02,1","01,99,1,99,9,99,9,99999,9,99,9,99,9","01,1","SYN05294733 11/75 10502 10260 20210 60004 70100 333 70000="
"94733099999","2019-01-04T04:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","090,1,N,0021,1","22000,1,9,N","025000,1,9,9","+0378,1","+0172,1","99999,9","06,0000,9,1",,"0,1,02,1","0,1,02,1","03,99,1,99,9,99,9,99999,9,99,9,99,9","03,1","SYN04294733 11/75 30904 10378 20172 60001 70300="
"94733099999","2019-01-04T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","290,1,N,0057,1","99999,9,9,N","020000,1,9,9","+0339,1","+0201,1","99999,9","24,0000,9,1",,"0,1,02,1","0,1,02,1",,"02,1","SYN05294733 11970 02911 10339 20201 60004 70200 333 70000="
"94733099999","2019-01-05T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","200,1,N,0026,1","99999,9,9,N","000100,1,9,9","+0209,1","+0193,1","99999,9","24,0004,3,1",,"1,1,02,1","1,1,02,1","08,99,1,99,9,99,9,99999,9,99,9,99,9","51,1","SYN05294733 11/01 82005 10209 20193 69944 75111 333 70004="
"94733099999","2019-01-08T04:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","070,1,N,0026,1","22000,1,9,N","025000,1,9,9","+0344,1","+0213,1","99999,9","06,0000,9,1",,"2,1,02,1","2,1,02,1","04,99,1,99,9,99,9,99999,9,99,9,99,9","02,1","SYN04294733 11/75 40705 10344 20213 60001 70222="
"""  # noqa: E501
gerrit
  • 17,590
  • 12
  • 72
  • 135
0

With a \ you can expand statements to multiple lines:

s = "this is my really, really, really, really, really, really" + \
"really long string that I'd like to shorten."

should work.

the Tin Man
  • 150,910
  • 39
  • 198
  • 279
Ikke
  • 90,705
  • 23
  • 91
  • 118
0

I tend to use a couple of methods not mentioned here for specifying large strings, but these are for very specific scenarios. YMMV...

  • Multi-line blobs of text, often with formatted tokens (not quite what you were asking, but still useful):

    error_message = '''
    I generally like to see how my helpful, sometimes multi-line error
    messages will look against the left border.
    '''.strip()
    
  • Grow the variable piece-by-piece through whatever string interpolation method you prefer:

    var = 'This is the start of a very,'
    var = f'{var} very long string which could'
    var = f'{var} contain a ridiculous number'
    var = f'{var} of words.'
    
  • Read it from a file. PEP-8 doesn't limit the length of strings in a file; just the lines of your code. :)

  • Use brute-force or your editor to split the string into managaeble lines using newlines, and then remove all newlines. (Similar to the first technique I listed):

    foo = '''
    agreatbigstringthatyoudonotwanttohaveanyne
    wlinesinbutforsomereasonyouneedtospecifyit
    verbatimintheactualcodejustlikethis
    '''.replace('\n', '')
    
Larold
  • 560
  • 2
  • 7
  • 18
0

Available options:

  • backslash: "foo" \ "bar"
  • plus sign followed by backslash: "foo" + \ "bar"
  • brackets:
    • ("foo" "bar")
    • brackets with plus sign: ("foo" + "bar")
    • PEP8, E502: the backslash is redundant between brackets

Avoid

Avoid brackets with comma: ("foo", "bar") which defines a tuple.


>>> s = "a" \
... "b"
>>> s
'ab'
>>> type(s)
<class 'str'>
>>> s = "a" + \
... "b"
>>> s
'ab'
>>> type(s)
<class 'str'>
>>> s = ("a"
... "b")
>>> type(s)
<class 'str'>
>>> print(s)
ab
>>> s = ("a",
... "b")
>>> type(s)
<class 'tuple'>
>>> s = ("a" + 
... "b")
>>> type(s)
<class 'str'>
>>> print(s)
ab
>>> 
Community
  • 1
  • 1
marcanuy
  • 19,934
  • 8
  • 56
  • 109
0

Using black [https://github.com/psf/black] I format it like this.

   help=f"""filters, lista de filtros para cargar las base de conocimiento.
   Pueden mandarse solo algunos filtros ya que no son obligatorios,
   por ejemplo, si no se manda sts, se cargarán todos las bases de todos los estados.""",
josuedjh
  • 342
  • 5
  • 11
-1

I've used textwrap.dedent in the past. It's a little cumbersome so I prefer line continuations now but if you really want the block indent, I think this is great.

Example Code (where the trim is to get rid of the first '\n' with a slice):

import textwrap as tw
x = """\
       This is a yet another test.
       This is only a test"""
print(tw.dedent(x))

Explanation:

dedent calculates the indentation based on the white space in the first line of text before a new line. If you wanted to tweak it, you could easily reimplement it using the re module.

This method has limitations in that very long lines may still be longer than you want in which case other methods that concatenate strings is more suitable.

MrMas
  • 1,013
  • 2
  • 14
  • 26