Многострочные строки и тексты
Тройные кавычки хранят текст с переводами строк: заказ из трёх строк, стихотворение, лог. Считаем длину многострочной строки, ловим отступы и режем текст методом 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 их отбрасывает, и каждую строку можно сразу чистить и разбирать.
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'))
1. Какие кавычки позволяют записать текст в несколько строк кода?
2. Что вернёт len('аб\нгд')?
3. Что возвращает метод splitlines()?
4. Что случится с отступами внутри тройных кавычек?
5. Сколько элементов даст 'хлеб\nмолоко\nсыр'.splitlines()?
6. Что вернёт len('аб\nгд')?
7. Что произойдёт с отступами внутри тройных кавычек?
8. Как убрать общий отступ у текста в тройных кавычках?
Дана заметка из трёх строк. Выведи три значения, каждое на своей строке: количество строк (через splitlines), вторую строку заметки и длину всей заметки в символах.
Что означает \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-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Строки · Урок 16
Выравнивание строк: ljust, rjust, center, zfill
ljust, rjust, center и zfill дотягивают строку до заданной ширины: ровные колонки прайса, заголовок по центру, номера заказов с ведущими нулями.
Строки · Урок 18
Строки и списки: перевод туда-обратно
Строка ведёт себя почти как список символов, но с одним запретом — на изменение. Учимся свободно переводить строку в список и обратно и использовать силу обоих миров.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
re · Урок 10
Флаги в регулярных выражениях: re.IGNORECASE, MULTILINE, DOTALL, VERBOSE
Четыре флага, которые меняют поведение целого движка: поиск в любом регистре, якоря на каждой строке, точка с переводом строки и шаблоны с комментариями вместо «полотна».
многострочный режим regexточка и перевод строки regex
Циклы · Урок 3
Python цикл по строке, словарю и строкам файла
for ходит не только по спискам: строка — последовательность символов, словарь перебирается по ключам, а items отдаёт готовые пары. Плюс построчный перебор текста файла.
python цикл по строкеfor по строке python
Строки · Урок 13
Экранирование и сырые строки
Как напечатать кавычку внутри кавычек и путь Windows, который не ломается? Знакомимся с обратным слэшем — символом, который меняет смысл следующего символа.
python перенос строкисырые строки python