Перейти к содержанию

412 уроков, 25 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 17 из 20 Начальный 20 мин 130 XP

Многострочные строки и тексты

Тройные кавычки хранят текст с переводами строк: заказ из трёх строк, стихотворение, лог. Считаем длину многострочной строки, ловим отступы и режем текст методом splitlines.

Редакция Питоники

До сих пор наши строки умещались в одну строку кода. Но отзыв — это абзац, заказ — несколько позиций, лог — десятки событий. Экранировать каждый перевод строки последовательностью \n, как в уроке 13, можно, но длинный текст в кавычках с россыпью \n нечитаем. Для таких текстов у Python есть тройные кавычки.

Тройные кавычки: текст как есть

Строка в тройных одинарных кавычках '''...''' (или тройных двойных) может тянуться сколько угодно строк кода: переводы строк внутри сохраняются в тексте. Открывающие кавычки стоят в конце строки кода, текст пишется дальше как есть, закрывающие кавычки — после последней строки текста.

заказ в три строки
order = '''Заказ № 45
покупатель: Анна
товары: хлеб, молоко'''
print(order)
Вывод
Заказ № 45
покупатель: Анна
товары: хлеб, молоко

Длина многострочной строки

len считает символы, и перевод строки — тоже символ. В строке из двух строк длиной 2 символа каждая сидит ещё один невидимый символ-разделитель, и len вернёт 5, а не 4: два плюс один плюс два.

длина двух строк
text = '''аб
гд'''
print(text)
print(len(text))
Вывод
аб
гд
5
отступы внутри тройных кавычек
lines = '''Первая:
    вторая с отступом'''
print(lines)
print(repr(lines))
Вывод
Первая:
    вторая с отступом
'Первая:\n    вторая с отступом'

Функция repr показывает строку «в Inside out»: с кавычками и невидимыми символами. В её выводе видно и перевод строки \n, и четыре пробела отступа — всё это честно лежит в строке и попадает в len.

splitlines: текст по строкам

Метод splitlines() режет многострочный текст на список строк и убирает переводы строк: трёхстрочный отчёт превращается в список из трёх элементов. Дальше каждая строка обрабатывается как обычная — срезами из урока 2 или split из урока 9. Именно так мы разберём отчёт в финальном проекте курса.

отчёт по строкам
report = '''молоко, 89
хлеб, 45
сыр, 540'''
lines = report.splitlines()
print(len(lines))
print(lines[0])
print(lines[-1])
Вывод
3
молоко, 89
сыр, 540

Как создать многострочную строку в Python

До сих пор строки умещались в одну строку кода. Но отзыв — это абзац, заказ — несколько позиций, лог — десятки событий. Экранировать каждый перевод строки последовательностью \n, как в уроке 13, можно, но длинный текст в кавычках с россыпью \n нечитаем. Для таких текстов у Python есть тройные кавычки.

заказ в три строки
order = '''Заказ № 45
покупатель: Анна
товары: хлеб, молоко'''
print(order)
Вывод
Заказ № 45
покупатель: Анна
товары: хлеб, молоко

Открывающие кавычки стоят в конце строки кода, текст пишется дальше как есть, закрывающие — после последней строки текста. Тройные кавычки бывают и двойные ("""...""") — разница только в том, какие кавычки могут встретиться внутри текста. Если внутри есть одинарная кавычка, берите двойные, и наоборот.

Длина многострочной строки

длина двух строк
text = '''аб
гд'''
print(text)
print(len(text))
Вывод
аб
гд
5

Это стоит запомнить, потому что счётчик строк и счётчик символов часто путают. Если файл содержит 1000 строк, len(текст) вернёт не 1000, а сумму длин всех строк плюс 999 переводов. А вот len(текст.splitlines()) даст ровно 1000 — потому что разделители будут отброшены.

отступы внутри тройных кавычек
lines = '''Первая:
    вторая с отступом'''
print(lines)
print(repr(lines))
Вывод
Первая:
    вторая с отступом
'Первая:\n    вторая с отступом'

Функция repr показывает строку «внутрь»: с кавычками и невидимыми символами. В её выводе видно и перевод строки \n, и четыре пробела отступа — всё это честно лежит в строке и попадает в len. repr — тот самый инструмент, которым стоит пользоваться, когда «текст выводится неправильно».

splitlines: текст по строкам

Метод splitlines() режет многострочный текст на список строк и убирает переводы строк: трёхстрочный отчёт превращается в список из трёх элементов. Дальше каждая строка обрабатывается как обычная — срезами из урока 2 или split из урока 9.

отчёт по строкам
report = '''молоко, 89
хлеб, 45
сыр, 540'''
lines = report.splitlines()
print(len(lines))
print(lines[0])
print(lines[-1])
Вывод
3
молоко, 89
сыр, 540

Именно так мы разберём отчёт в финальном проекте курса. Обратите внимание, что переводов строк в элементах списка нет — splitlines их отбрасывает, и каждую строку можно сразу чистить и разбирать.

splitlines против split
text = 'раз\nдва'
print(text.splitlines())
print(text.split('\n'))
print(len(text), len(text.splitlines()))
Вывод
['раз', 'два']
['раз', 'два']
7 2

Здесь оба способа дали одинаковый результат — потому что перевод был «unix»-овый. Разница проявится на Windows-файле. А третья строка показывает разницу в счёте: 7 символов в строке против 2 строк в списке. Числа разные, и их нельзя путать: len текста — это размер в памяти и в байтах примерно, len(lines) — это количество записей.

СпособЧто получитсяКогда брать
'''текст'''многострочная строкаписьма, описания, шаблоны
len(текст)число символов вместе с переводамипроверка размера текста
len(текст.splitlines())число строкподсчёт записей в логе
текст.splitlines()список строк без переводовпострочная обработка
текст.split('\n')список, где \r может остатьсятолько для unix-текста
repr(текст)видимое содержимое строкиотладка невидимых символов

Отдельный сюжет — текст, прочитанный из файла, где в конце всегда есть перевод строки. open('log.txt').read() вернёт строку, заканчивающуюся на \n, и splitlines() на такой строке даст список без лишнего пустого элемента. А вот split('\n') даст пустую строку последним элементом — и цикл по нему упадёт, если вы будете разбирать элементы как записи.

И последнее. Тройные кавычки — не отдельный тип данных, а просто удобная запись обычной строки. Внутри них работают те же escape-последовательности, что и в одинарных кавычках, плюс сам перевод строки. Если внутри текста встречается тройная кавычка, её нужно экранировать — иначе строка закончится раньше времени. На практике это бывает в текстах с примерами кода.

Когда многострочный текст удобнее списка строк

Иногда текст удобнее хранить не списком строк, а одной многострочной строкой. Разница не в том, как выглядит результат, а в том, как с ним работают. Строка — это то, что вы получаете из файла, из ответа API, из документа. Список строк — это то, с чем удобно считать.

один текст и список строк
text = '''молоко, 89
хлеб, 45
сыр, 540'''
lines = text.splitlines()
print(len(text), len(lines))
print(text.splitlines()[0] == lines[0])
Вывод
28 3
True

Длина строки 21, а строк три — разница в 18 символов: это 12 букв и два перевода, плюс запятые и пробелы. Числа разные, и их полезно знать: длину текста сравнивают с лимитом API, а количество строк — с ожидаемым числом записей.

Ещё один случай — текст, в котором переводы строк НЕ должны быть структурой. Например, описание товара с переносами для вёрстки. Тогда его хранят в тройных кавычках и НЕ вызывают splitlines: переводы строк тут часть содержания, а не разделитель записей. Разница в одном вызове метода, а в данных — принципиальная.

И последнее. Тройные кавычки внутри кода часто выглядят как «способ записать текст», но их настоящая сила в другом: они позволяют держать в коде образец документа, с которым потом сравнивают реальные данные. Пример: шаблон письма, ожидаемый ответ сервера, образец лог-файла. Текст виден целиком, с переносами, и сравнение идёт построчно.

Когда многострочный текст удобнее списка строк

один текст и список строк
text = '''молоко, 89
хлеб, 45
сыр, 540'''
lines = text.splitlines()
print(len(text), len(lines))
print(text.splitlines()[0] == lines[0])
Вывод
28 3
True

Текст в коде: как его не испортить

Многострочный текст внутри кода — это тоже данные, и к ним применимы все правила нормализации. Проблема в том, что текст пишут руками, а потом читают программно, и расхождение между «как выглядит» и «что внутри» стоит дорого.

проверка многострочного текста
template = '''Привет, {name}!
Ваш заказ №{order} отправлен.'''
print(len(template))
print(template.count('{'))
print(template.format(name='Анна', order=105))
Вывод
45
2
Привет, Анна!
Ваш заказ №105 отправлен.

Здесь 45 символов и ровно два шаблонных поля. Проверка через count('{') — дешёвый способ убедиться, что шаблон не потерял плейсхолдер при копировании из документации. А format с именованной подстановкой превращает текст в рабочий шаблон — тот самый приём, о котором шла речь в уроке про format().

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

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

text = '''раз
два'''
print(len(text))
print(len(text.splitlines()))
report = 'молоко: 1
хлеб: 2'
lines = report.splitlines()
print(lines[1])
s = '''хлеб
молоко
сыр'''
print(s.count('\n'))
Проверь себя
0 / 8

1. Какие кавычки позволяют записать текст в несколько строк кода?

2. Что вернёт len('аб\нгд')?

3. Что возвращает метод splitlines()?

4. Что случится с отступами внутри тройных кавычек?

5. Сколько элементов даст 'хлеб\nмолоко\nсыр'.splitlines()?

6. Что вернёт len('аб\nгд')?

7. Что произойдёт с отступами внутри тройных кавычек?

8. Как убрать общий отступ у текста в тройных кавычках?

Карточки терминов
Запомнено: 0 / 6
Практика

Дана заметка из трёх строк. Выведи три значения, каждое на своей строке: количество строк (через splitlines), вторую строку заметки и длину всей заметки в символах.

practice.py
Вопросы и ответы по уроку

Что означает \n в строке?

Это escape-последовательность для перевода строки — один невидимый символ. print встречает его и продолжает вывод с новой строки. В len такой символ считается за единицу.

Урок 13: экранирование и сырые строки

Почему в многострочной строке появились лишние пробелы?

Скорее всего, строки текста внутри тройных кавычек сдвинуты вправо: отступы становятся частью строки. Проверить это помогает repr — он покажет и пробелы, и переводы строк, которые обычно не видны.

Как сделать многострочную строку в Python?

Заключить текст в тройные кавычки: '''текст''' или """текст""". Переводы строк внутри такой строки сохраняются, а сам текст в коде можно писать в несколько строк — так оформляют длинные сообщения и docstring'и функций.

Урок 17: многострочные строки

Что означает \n в строке?

Это escape-последовательность для перевода строки — один невидимый символ. print встречает его и продолжает вывод с новой строки. В len такой символ считается за единицу: 'аб\nгд' — это пять символов, а не четыре.

Урок 13: экранирование и сырые строки

Почему в многострочной строке появились лишние пробелы?

Скорее всего, строки текста внутри тройных кавычек сдвинуты вправо: отступы становятся частью строки. Проверить это помогает repr — он покажет и пробелы, и переводы строк, которые обычно не видны.

Как разбить многострочный текст на отдельные строки?

Методом splitlines(): он вернёт список строк, убрав переводы строк. Похожий результат даёт split('\n'), но splitlines надёжнее — он понимает и другие виды переводов строк, например Windows-формат \r\n.

Как убрать общий отступ у многострочного текста?

Функцией textwrap.dedent: она срезает общий префикс пробелов из всех строк. Это удобно для текстов, написанных с отступом внутри функции, — без dedent отступы кода стали бы частью строки.

Понравился урок? Сошлитесь на него

«До сих пор наши строки умещались в одну строку кода.»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Что дальше

Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.