Как я могу разбить эту длинную строку в Python?


176

Как бы вы отформатировали длинную строку, такую ​​как эта? Я хотел бы получить не более 80 символов в ширину:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

Это мой лучший вариант?

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))

1
Похоже, хороший вариант. Что тебе не нравится в этом?
Хэмиш Грубиджан

2
Немного субъективно, не правда ли? :)
Адам Во

1
related: stackoverflow.com/questions/1940710/… (конкатенация строк в python)
jldupont

14
Вы можете сохранить персонажа, удалив неправильный 'в' это '.
Jball

2
indexes: Правильное множественное число indexесть indices.
Скраффи

Ответы:


336

Это начало. Неплохая практика - определять более длинные строки вне кода, который их использует. Это способ отделить данные и поведение. Ваш первый вариант - неявно соединять строковые литералы, делая их смежными:

("This is the first line of my text, "
"which will be joined to a second.")

Или с продолжением конца строки, которое немного более хрупко, так как это работает:

"This is the first line of my text, " \
"which will be joined to a second."

Но это не так:

"This is the first line of my text, " \ 
"which will be joined to a second."

Увидеть разницу? Нет? Ну, вы не будете, когда это ваш код тоже.

Недостатком неявного объединения является то, что оно работает только со строковыми литералами, а не со строками, взятыми из переменных, поэтому при рефакторинге все может стать немного сложнее. Кроме того, вы можете интерполировать только форматирование объединенной строки в целом.

Кроме того, вы можете присоединиться явно, используя оператор конкатенации ( +):

("This is the first line of my text, " + 
"which will be joined to a second.")

Явное лучше, чем неявное, как говорит дзен Python, но это создает три строки вместо одной и использует вдвое больше памяти: есть две написанные вами, плюс одна, которая является двумя из них, соединенными вместе, так что вы Нужно знать, когда игнорировать дзен. Положительным моментом является то, что вы можете применять форматирование к любой из подстрок отдельно в каждой строке или ко всей партии вне скобок.

Наконец, вы можете использовать строки в тройных кавычках:

"""This is the first line of my text
which will be joined to a second."""

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

"""This is the first line of my text \
which will be joined to a second."""

Это имеет ту же проблему, что и та же техника, описанная выше, в том, что правильный код отличается от неправильного кода только невидимым пробелом.

Какой из них «лучший», зависит от вашей конкретной ситуации, но ответ не просто эстетический, но один из слегка отличающихся поведений.


26
Компилятор CPython максимально оптимизирует операции с литералами, что означает, что добавление двух строковых литералов приводит к получению только одного строкового литерала в байт-коде.
Игнасио Васкес-Абрамс

2
В то время как все ответы, которые я получил, полезны, ваш, безусловно, помогает мне понять все способы разбить строки. Была ли проблема с окончанием строки "\", что после нее был пробел?
Гатстер

1
Я не вижу здесь никакой разницы, но, в основном, это из-за довольно примитивной окраски синтаксиса SO. (Какой-то совершенно хороший код практически не читается в SO, но только потому, что он написан не на языке, синтаксис которого очень близок к C.) Весьма необычно, чтобы ваш редактор вызывающе выделял конечные пробелы, поскольку они редко бывают полезными (или преднамеренными) , :-)
Кен

1
@KhurshidAlam вы можете использовать одинарные кавычки, 'чтобы содержать эту строку, или избегать двойных кавычек внутри вашей строки, или использовать тройные двойные кавычки """. Проблема со строками в кавычках, содержащими кавычки, одинакова, независимо от того, используете ли вы одну или несколько строк для определения литеральной строки.
hugovdberg

1
Мой редактор всегда удаляет конечные пробелы. Я рекомендую вам включить ту же настройку. Конечно, пробелы в новой строке все еще являются частью строки, поэтому я в конечном итоге использовал +.
ThaJay

46

Последовательные строковые литералы объединяются компилятором, а выражения в скобках считаются одной строкой кода:

logger.info("Skipping {0} because it's thumbnail was "
  "already in our system as {1}.".format(line[indexes['url']],
  video.title))

11

Лично мне не нравится вешать открытые блоки, поэтому я отформатировал бы это как:

logger.info(
    'Skipping {0} because its thumbnail was already in our system as {1}.'
    .format(line[indexes['url']], video.title)
)

В общем, я бы не стал слишком усердно бороться, чтобы код точно вписался в строку из 80 столбцов. Стоит сохранить длину линии до разумного уровня, но жесткий предел 80 остается в прошлом.


8
Это на самом деле не вещь прошлого. Стандартная библиотека Python все еще использует PEP8 в качестве руководства по стилю, поэтому правило все еще существует, и многие люди (включая меня) следуют ему. Это удобное место для рисования линии.
Девин Жанпьер

3
Интересно, сколько проектов все еще следуют правилу 80 символов? Для среднего размера окна, который я использую, я думаю, что 100-120 более продуктивен для меня, чем 80 символов.
Гатстер

1
Да, это тоже касается длины линии, которую я использую, хотя [ужас! кощунство!] Я использую пропорциональный шрифт, поэтому точная длина линии не так критична. Это скорее пример того, сколько логики в одной строке читается, чем сколько символов, как таковых ... если у меня есть длинная строка данных, которую никто не должен читать, я с удовольствием позволю ей выплеснуться 120.
2010 г.

Пропорциональные шрифты для кода - я с тобой, брат. Судя по отвращению всех, с кем я когда-либо работал, к ним пришел мир, но он еще не готов.
Jlarcombe

4
~ 80 символов также упрощают одновременное отображение двух файлов на одном экране. Кроме того, если вы что-то отлаживаете во время чрезвычайной ситуации на консоли сервера, вы действительно оцените ограничение в 80 символов! :)
Мик Т

4

Вы можете использовать модуль textwrap, чтобы разбить его на несколько строк

import textwrap
str="ABCDEFGHIJKLIMNO"
print("\n".join(textwrap.wrap(str,8)))

ABCDEFGH
ИЙКЛИМНО

Из документации :

TextWrap. wrap (text [, width [, ...]])
Переносит один абзац в текст (строку), поэтому каждая строка имеет длину не более ширины символов. Возвращает список выходных строк без заключительных строк новой строки.

Необязательные ключевые аргументы соответствуют атрибутам экземпляра TextWrapper, описанным ниже. ширина по умолчанию 70.

См. TextWrapper.wrap()Метод для получения дополнительной информации о том, как ведет себя wrap ().


2

Для тех, кто также пытается вызвать .format()длинную строку и не может использовать некоторые из самых популярных методов переноса строк, не прерывая последующий .format(вызов, вы можете сделать это str.format("", 1, 2)вместо "".format(1, 2). Это позволяет вам разрывать строку с любой техникой, которая вам нравится. Например:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

возможно

logger.info(str.format(("Skipping {0} because its thumbnail was already"
+ "in our system as {1}"), line[indexes['url']], video.title))

В противном случае единственная возможность - использовать продолжения конца строки, которыми я лично не являюсь поклонником.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.