Як написати дуже довгий рядок, який відповідає PEP8 та запобігає E501


203

Оскільки PEP8 пропонує зберігати нижче правила 80 стовпців для вашої програми python, як я можу дотримуватися цього з довгими рядками, тобто

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

Редагувати Поміркуючи, я погоджуюся, що пропозиція Тодда використовувати дужки, а не продовження рядків, краще з усіх причин, які він наводить. Єдине вагання, яке я маю, це те, що порівняно легко сплутати обрешітки з рядками.


4
Ось чому я відчув себе ідіотю, що розміщує запитання. Ура.
Федерер

8
Це продовження рядків шляхом виходу з кінцевої лінії, а не просто неявного конкатекації, і до недавнього часу явно заборонено в PEP8, хоча зараз є припущення, але НЕ для довгих рядків. Відповідь Тодда нижче правильна.
Аарон Холл

4
Мені подобається PEP8, але це частина PEP8, яка мені не подобається. Я відчуваю, що неявне продовження зрозуміліше, через можливість сплутати кортежі
monknomo

1
Не пам’ятайте, що не додавати порожніх пробілів після \
Mrinal Saurabh

що робити, якщо довгий рядок знаходиться посередині довгої багаторядкової струни?
Тайне

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

Я використав пошук в Google "довжина лінії python", яка повертає посилання PEP8 як перший результат, а також посилається на інший хороший пост StackOverflow на цю тему: " Чому Python PEP-8 повинен визначати максимальну довжину рядка 79 символів? "

Ще однією вдалою пошуковою фразою було б "продовження лінії пітона".


8
+1: "Особисто мені не подобаються
нахили від нахилу

13
Для всіх, хто отримує кортеж і цікавиться, чому. Не додайте коми до кінця рядків тут, це призведе до кортежу, а не до рядка. ;)
bugmenot123

7
Чи не додавання символу + є більш явним, ніж наведений приклад? Я б все-таки вважав це неявним. тобто, "str1" + "str2"а не"str1" "str2"
user1318135

4
Я фактично погоджуюся, що знак плюс є більш явним, але це робить іншу річ. Це перетворює рядок у вираження, що підлягає оцінці, а не вказує константу однієї струни у кількох елементах. Я не впевнений, але я думаю, що це робиться під час розбору, тоді як вираз потрібно виконати пізніше. Різниця в швидкості, мабуть, незначна, якщо їх не існує величезна кількість. Але також естетично я віддаю перевагу автоматичному конкатенації, оскільки це один менш стислий символ на рядок.
Тодд

4
Цей синтаксис також зберігає можливість застосувати форматування рядків на зразок:('this is my really, really, really, really, really long {} ' 'that I'd really, really, really, like to {}').format(var1, var2))
Тим

16

Я думаю, що найважливішим словом у вашому запитанні було "пропозиції".

Стандарти кодування - це смішні речі. Часто вказівки, які вони надають, мають справді добру основу, коли вони були написані (наприклад, більшість терміналів не в змозі відобразити> 80 символів на рядку), але з часом вони стають функціонально застарілими, але все ще жорстко дотримуються. Я здогадуюсь, що вам тут потрібно зробити, це зважити відносні достоїнства "порушення" цієї конкретної пропозиції проти читабельності та збереженості коду.

Вибачте, це не відповідає безпосередньо на ваше запитання.


Я цілком погоджуюся. Існує аналогічне правило стилю Java, яке також застаріло (IMHO).
Ікер Хіменес

Так, я погоджуюся, однак мені ламають голову, як я б дотримувався цього в цьому конкретному прикладі. Я завжди намагаюся дотримуватись класів, методів до <80 символів, однак я б сказав, що такий рядок не має іншого ефекту, крім, можливо, негативного.
Федерер

1
Вам також потрібно зважити свої особисті переваги щодо загальноприйнятих стандартів кодування. Ви хочете, щоб нові люди могли завітати та зручніше з форматуванням коду з першого дня.
ретрансляція

1
Я знаю, що я власноруч намагаюся дотримуватися межі 80 символів лише тому, що я все ще роблю більшу частину кодування в IDLE і мені не подобається, як вона обробляє горизонтальну прокрутку. (Без смуги прокрутки)
Tofystedeth

@retracile - так, ти. Я не кажу "Ви повинні ігнорувати настанови", скоріше припускаючи, що в деяких випадках вказівки необов'язково існують для блага громади. Мені не було відомо про обмеження IDLE (як опублікував Tofystedeth), але в цьому випадку є аргумент striong для дотримання конвенції.
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."

Парени також працюватимуть замість продовження рядка, але ви ризикуєте, що хтось подумає, що маєте намір мати кортеж і щойно забув кому. Візьмемо для прикладу:

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

При динамічному введенні Python код може працювати в будь-якому випадку, але створювати неправильні результати з тим, якого ви не мали наміру.


2

Зворотна коса:

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
Зверніть увагу, що плюс необхідний. Python об'єднує рядкові літерали, які слідують один за одним.
bukzor

2

Все це чудові відповіді, але я не зміг знайти плагін редактора, який би допоміг мені редагувати "неявно об'єднані" рядки, тому я написав пакет, щоб полегшити мені.

На pip (встановіть абзаци), якщо той, хто блукає цією старою темою, хотів би перевірити її. Форматує багаторядкові рядки так, як це робить 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 не обмежує довжину рядків у файлі; лише рядки вашого коду. :)

  • Використовуйте грубу силу або редактор, щоб розділити рядок на керовані рядки за допомогою нових рядків, а потім видалити всі нові рядки. (Подібно до першої техніки, яку я перерахував):

    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 закрився, ви можете використовувати директиви щодо закривання . Наприклад, у процесі тестування я визначив деякі підроблені дані 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 = """щоб уникнути першого нового рядка.
Майкл Данн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.