6

Правильное выравнивание многострочных строк?

34

Заголовок: Как правильно форматировать многострочные строки в Python внутри функции?

Содержимое вопроса:

Какое корректное выравнивание для многострочных строк в Python, находящихся внутри функции?

Рассмотрим два варианта:

    def method():
        string = """line one
line two
line three"""

или

    def method():
        string = """line one
        line two
        line three"""

Или есть какой-то другой способ?

Первый пример выглядит слегка странно, так как строка кажется "вынесенной" за границы функции.

5 ответ(ов)

0

Один из вариантов, который, кажется, отсутствует в других ответах (упомянут только в комментарии от naxa внизу), выглядит следующим образом:

def foo():
    string = ("строка первая\n"          # Добавляем \n в строке
              "строка вторая"  "\n"      # Добавляем "\n" после строки
              "строка третья\n")

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

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

0

В Ipython с включённым pylab в пространстве имён уже доступна функция dedent. Я проверил, она принадлежит библиотеке matplotlib. Также можно импортировать её следующим образом:

from matplotlib.cbook import dedent

В документации говорится, что она работает быстрее, чем аналогичная функция из модуля textwrap, и в моих тестах в Ipython она действительно оказалась в 3 раза быстрее в среднем. Ещё одно преимущество dedent заключается в том, что она отбрасывает любые ведущие пустые строки, что позволяет гибко конструировать строки:

"""
строка 1
строка 2
"""

"""\
строка 1
строка 2
"""

"""строка 1
строка 2
"""

Используя dedent от matplotlib на этих трёх примерах, мы получим одинаковый осмысленный результат. В то время как функция dedent из textwrap в первом примере создаст ведущую пустую строку.

Очевидный недостаток заключается в том, что textwrap находится в стандартной библиотеке, а matplotlib является внешним модулем.

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

Когда мне нужна не очень длинная строка в коде, я использую следующий, хоть и неэстетичный, код, где я позволяю длинной строке выходить за рамки окружающего отступа. Это явно нарушает принцип "Красивое лучше, чем уродливое", но можно утверждать, что он проще и более очевиден, чем альтернатива с dedent.

def example():
    long_string = '''\
Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip.\
'''
    return long_string

print(example())
0

Если вам нужно быстрое и простое решение, чтобы избежать лишних переноса строк, вы можете воспользоваться списком, например:

def func(*args, **kwargs):
    string = '\n'.join([
        'первая строка очень длинной строки и',
        'вторая строка той же длинной строки и',
        'третья строка ...',
        'и так далее...',
    ])
    print(string)
    return

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

0

Я предпочитаю следующий способ:

def method():
    string = \
"""\
line one
line two
line three\
"""

или

def method():
    string = """\
line one
line two
line three\
"""

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

0

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

def foo():
    return "{}\n"\
           "freq: {}\n"\
           "temp: {}\n".format(time, freq, temp)

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь