PEP8을 준수하고 E501을 방지하는 매우 긴 문자열을 작성하는 방법


203

PEP8이 파이썬 프로그램에 대해 80 열 규칙 이하로 유지할 것을 제안함에 따라 긴 문자열로 어떻게 그것을 준수 할 수 있습니까?

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

이것을 다음 줄로 확장하는 방법은 무엇입니까?

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

답변:


116

암시 적 연결이 가장 깨끗한 솔루션 일 수 있습니다.

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

편집 반영 나는 줄 연속 대신 대괄호를 사용하는 Todd의 제안이 그가주는 모든 이유로 더 낫다는 것에 동의합니다. 내가 가진 유일한 주저는 괄호로 묶인 줄과 튜플을 혼동하기가 비교적 쉽다는 것입니다.


4
이것이 내가 질문을 게시하는 바보처럼 느껴지는 이유입니다. 건배.
Federer

8
이것은 암묵적 연결뿐만 아니라 PEP8에서 매우 최근에 명시 적으로 금지 될 때까지 끝줄을 피함으로써 줄 연속입니다. 아래 Todd의 답변이 맞습니다.
Aaron Hall

4
나는 PEP8을 좋아하지만 이것은 내가 싫어하는 PEP8의 일부입니다. 나는 암시 계속 때문에 튜플 혼동의 가능성, 명확 같은 느낌
monknomo


긴 줄이 긴 여러 줄 문자열의 중간에 있으면 어떻게합니까?
Thayne

298

또한 인접한 문자열 상수가 자동으로 연결되므로 다음과 같이 코딩 할 수도 있습니다.

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

더하기 부호는 없으며 예제 형식에 따라 쉼표와 공백을 추가했습니다.

개인적으로 나는 백 슬래시를 좋아하지 않으며 어딘가에서 더 명백한이 형식을 선호하여 사용이 실제로 사용되지 않는 곳을 읽는 것을 상기합니다. "명시적인 것이 묵시적인 것보다 낫다"는 것을 기억하십시오.

백 슬래시는 실제로 줄 바꿈 문자를 벗어나기 때문에 덜 명확하고 덜 유용하다고 생각합니다. 필요한 경우 줄 끝 주석을 붙일 수 없습니다. 연결된 문자열 상수를 사용하여이 작업을 수행 할 수 있습니다.

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

PEP8 링크를 첫 번째 결과로 반환하는 "python line length"라는 Google 검색을 사용했지만이 주제에 대한 또 다른 좋은 StackOverflow 게시물에 대한 링크도 있습니다. " Python PEP-8에서 최대 줄 길이를 79 자로 지정해야하는 이유는 무엇입니까? "

또 다른 좋은 검색 문구는 "python line continuation"입니다.


8
+1 : "개인적으로 백 슬래시가
마음에 들지 않으며이

13
튜플을 얻고 그 이유를 궁금해하는 모든 사람에게 적합합니다. 여기 줄 끝에 쉼표를 추가하지 마십시오. 문자열이 아닌 튜플이 생성됩니다. ;)
bugmenot123

7
주어진 예제보다 + 문자를 더 명확하게 추가하지 않습니까? 나는 여전히 이것이 암시 적이라고 생각할 것이다. 즉"str1" + "str2""str1" "str2"
user1318135

4
나는 더하기 부호가 더 명백하다는 데 실제로 동의하지만 다른 일을합니다. 단일 문자열 상수를 여러 조각으로 지정하지 않고 문자열을 평가할 표현식으로 바꿉니다. 확실하지는 않지만 구문 분석 중에 수행되지만 표현식은 나중에 실행해야한다고 생각합니다. 속도 차이가 많지 않으면 속도 차이는 무시할 수 있습니다. 그러나 미적으로 나는 자동 연결을 선호합니다. 한 줄에 덜 까다롭기 때문입니다.
Todd

4
이 구문은 또한 다음과 같은 문자열 형식을 적용 할 가능성을 유지합니다.('this is my really, really, really, really, really long {} ' 'that I'd really, really, really, like to {}').format(var1, var2))
Tim

16

귀하의 질문에서 가장 중요한 단어는 "제안"이었습니다.

코딩 표준은 재미있는 것입니다. 그들이 제공하는 지침은 종종 작성 될 때 (예를 들어, 대부분의 터미널이 한 줄에 80자를 초과 할 수 없음) 아주 좋은 근거를 갖지만, 시간이 지남에 따라 기능적으로 폐기되었지만 여전히 엄격하게 준수합니다. 여기서해야 할 일은 코드의 가독성과 유지 가능성에 대한 특정 제안을 "파괴"하는 상대적인 장점을 평가하는 것입니다.

죄송합니다. 귀하의 질문에 직접 답변하지 않습니다.


전적으로 동의합니다. 더 이상 사용되지 않는 유사한 Java 스타일 규칙이 있습니다 (IMHO).
Iker Jimenez

예, 동의합니다. 그러나이 특정 예에서 머리를 지키는 방법을 이해하고 있습니다. 나는 항상 클래스, 메소드를 <80 문자로 유지하려고 노력하지만, 이와 같은 문자열은 아마도 부정적인 것 이외의 효과가 없다고 말하고 싶습니다.
Federer

1
또한 커뮤니티 전체 코딩 표준과 비교하여 개인 취향을 평가해야합니다. 새로운 사람들이 들어 와서 첫날부터 코드 형식에 익숙해지기를 원합니다.
2009

1
나는 내 자신을 알고있다. 나는 여전히 IDLE에서 코딩의 대부분을 수행하고 가로 스크롤을 처리하는 방식이 마음에 들지 않기 때문에 80 자 제한을 고수하는 경향이있다. (스크롤 바 없음)
Tofystedeth

@retracile-그렇습니다. 나는 "당신은 지침을 무시해야한다"고 말하지 않고, 어떤 경우에는 지침이 반드시 공동체의 이익을 위해 존재하는 것은 아니라고 제안합니다. 나는 IDLE의 제한 사항을 알지 못했지만 (Tofystedeth에 의해 게시 됨) 그 경우 협약 준수에 대한 논쟁이 있습니다.
ZombieSheep

13

당신은 공간을 잃었고, 아마도 줄 연속 문자가 필요할 것입니다. \.

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

또는:

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

Parens는 줄 연속 대신 작동하지만 튜플이 있다고 생각하고 쉼표를 잊어 버렸다고 생각하는 사람이 위험 할 수 있습니다. 예를 들어 보자.

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

대:

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

파이썬의 동적 타이핑을 사용하면 코드가 어느 쪽이든 실행될 수 있지만 의도하지 않은 결과로 잘못된 결과가 생성 될 수 있습니다.


2

백 슬래시 :

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

또는 parens로 감싸십시오 :

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

2
더하기가 필요합니다. 파이썬은 서로 따르는 문자열 리터럴을 연결합니다.
bukzor

2

이것들은 모두 훌륭한 답변이지만 "암시 적으로 연결된"문자열을 편집하는 데 도움이되는 편집기 플러그인을 찾을 수 없으므로 패키지를 작성하여 더 쉽게 만들었습니다.

이 오래된 실을 방황하는 사람이 그것을 확인하고 싶다면 핍 (설치 단락)에서. html과 같이 여러 줄 문자열을 형식화합니다 (공백, 두 개의 줄 바꿈, 줄 사이의 공백에 대한 걱정 없음).

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")

된다 ...

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

모든 것이 (Vim) 'gq'와 쉽게 정렬됩니다.


0

를 사용하면 \명령문을 여러 줄로 확장 할 수 있습니다.

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

작동해야합니다.


0

큰 문자열을 지정하기 위해 여기에 언급되지 않은 몇 가지 방법을 사용하는 경향이 있지만 매우 구체적인 시나리오를위한 것입니다. YMMV ...

  • 종종 형식이 지정된 토큰이있는 여러 줄의 텍스트 블랍 (요청한 것은 아니지만 여전히 유용합니다) :

    error_message = '''
    I generally like to see how my helpful, sometimes multi-line error
    messages will look against the left border.
    '''.strip()
  • 원하는 문자열 보간 방법을 통해 변수를 하나씩 확장하십시오.

    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.'
  • 파일에서 읽습니다. PEP-8은 파일에서 문자열의 길이를 제한하지 않습니다. 코드 줄만. :)

  • brute-force 또는 편집기를 사용하여 줄 바꿈을 사용하여 문자열을 managaeble 행으로 분할 한 다음 모든 줄 바꿈을 제거하십시오. (내가 열거 한 첫 번째 기술과 유사) :

    foo = '''
    agreatbigstringthatyoudonotwanttohaveanyne
    wlinesinbutforsomereasonyouneedtospecifyit
    verbatimintheactualcodejustlikethis
    '''.replace('\n', '')

0

사용 가능한 옵션 :

  • 백 슬래시 :"foo" \ "bar"
  • 더하기 부호백 슬래시 :"foo" + \ "bar"
  • 괄호 :
    • ("foo" "bar")
    • 괄호더하기 기호 :("foo" + "bar")
    • PEP8, E502 : 백 슬래시는 괄호 사이에 중복

기피

("foo", "bar")튜플을 정의하는 쉼표로 괄호를 사용하지 마십시오 .


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

0

긴 문자열 리터럴을 삽입해야하고 flake8을 종료하려면 shutdown 지시어를 사용할 수 있습니다 . 예를 들어 테스트 루틴에서 가짜 CSV 입력을 정의했습니다. 행이있는 더 많은 행으로 나누면 상당히 혼란 스러울 수 있으므로 # noqa: E501다음과 같이 추가하기로 결정했습니다 .

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

-1

과거에는 textwrap.dedent를 사용했습니다. 조금 번거롭기 때문에 지금 줄 연속을 선호하지만 실제로 블록 들여 쓰기를 원한다면 이것이 훌륭하다고 생각합니다.

예제 코드 (자르기가 슬라이스로 첫 번째 '\ n'을 제거하는 위치) :

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

설명:

dedent는 새 줄 앞의 첫 번째 텍스트 줄에있는 공백을 기준으로 들여 쓰기를 계산합니다. 조정을 원한다면 re모듈을 사용하여 쉽게 다시 구현할 수 있습니다 .

이 방법은 매우 긴 행이 원하는 것보다 여전히 길 수 있다는 제한이 있습니다.이 경우 문자열을 연결하는 다른 방법이 더 적합합니다.


1
트리밍 대신 에 첫 번째 줄 바꿈을 피하기 위해 x[1:]백 슬래시를 넣을 수 있습니다 x = """.
Michael Dunn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.