Форматированные строки в Python: примеры использования
Ваши строки никогда не были такими ясными, мощными, красивыми.


художественно-промышленная академия имени А. Л. Штиглица
Форматирование и вывод строк — одна из наиболее типичных задач в любом языке программирования. Однако в Python до версии 3.6 у нас было, по большому счёту, всего два способа:
- оператор %;
- функция format().
Хотя они оба вполне работали в простых случаях, вывод хоть сколько-нибудь сложных строк был настоящей болью. Только взгляните на этих монстриков:
str_1 = "Name: %s, email: %s, phone: %s" % (name, email, phone)
str_2 = "Name: {}, email: {}, phone: {}".format(name, email, phone)
Что там говорят на вводных уроках про читаемость кода в Python?
Первый вариант никуда не годен: мало того что надо бегать глазами туда-сюда по строке, — надо ещё помнить о ключах после символа % (для разных типов они разные, s — для строк) и не забыть поставить ещё один % между строкой и кортежем с переменными.
Второй вариант, то есть функция .format(), чуть получше, так как параметры-заменители в фигурных скобках облегчают читаемость, но всё равно не вполне подходит для строк с большим количеством переменных.
Так жить нельзя, решил однажды Гвидо ван Россум, и в версии 3.6 появились
f-strings, они же formatted string literals, — литералы форматированных строк. Или просто форматированные строки, эф-строки, или даже, не побоимся этого слова, эф-стринги. Строки в Python’е стали «питоничнее» — компактнее, удобнее, читаемее.

Базовый синтаксис f-строк
Синтаксис форматированных строк прост и прям. Вы добавляете перед строкой, прямо перед открывающими двойными или одинарными кавычками, букву f. Всё, строка теперь форматированная.
print(f"Hello f-strings")
>>> Hello f-string
Теперь можно вставлять туда переменные в уже знакомых нам фигурных скобках:
name = "f-strings" # переменная
print(f"Hello {name}")
>>> Hello f-strings
Правда ведь, стало проще и яснее? Не надо бегать взглядом в конец строки и обратно, чтобы понять, где и какая переменная выводится: всё прямо под рукой и перед глазами. И это только самое начало, едем дальше.
Вычисление выражений и вызов функций
Фигурные скобки, несмотря на свой игривый вид, таят в себе большие возможности. Внутри них можно вызывать функции, элементы списков и словарей, а также выполнять операции — нужно просто вставить соответствующие выражения.
num = 7
print(f'{num} в квадрате равно {num * num}')
>>> 7 в квадрате равно 49
Вызовем строковую функцию .upper(), превращающую все буквы строки в заглавные:
name = "спарта"
print(f"Это {name.upper()}!!!")
>>> Это СПАРТА!!!
Думаем, принцип ясен. Вот ещё пример с вызовом элементов словаря.
dict = {'name': 'Коля', 'profession': 'программист'}
print(f"{dict['name']} - это наш {dict['profession']}")
>>> Коля - это наш программист
Обратите внимание, что для строки и для ключей словаря вам нужно использовать разные кавычки. Например, двойные кавычки для f-строки и одинарные для ключей, как выше, или наоборот. Иначе будет синтаксическая ошибка — Python не поймёт, где строка, а где параметр.
Вывод кавычек и фигурных скобок
Но что, если нужно напечатать оба вида кавычек? Для начала можно попробовать старый добрый бэкслеш, или обратную косую черту. Она изолирует символ, идущий за ней, и позволяет вывести те же самые кавычки, которые оформляют основную строку.
print(f"Привет, \"{name}\", я 'Саша'")
>>> Привет, "Коля", я 'Саша'
Но внутри фигурных скобок форматированной строки бэкслеш не поддерживается. Увы. Поэтому следующий код вызовет ошибку:
list_a = ['a', 'b', 'c']
print(f"{'\n'.join(list_a)}")
>>> SyntaxError: f-string expression part cannot include a backslash
Наиболее простой и разумный путь избежать этого — вычислить выражение с бэкслешем заранее и только затем передать его в форматированную строку:
x = "\n".join(list_a)
print(f"{x}")
>>> a
>>> b
>>> c
Аналогично: что, если нам нужно вывести фигурные скобки в форматированной строке? Для начала стоит заметить, что фигурные скобки в f-строках не могут быть пустыми.
print(f'{}')
>>> SyntaxError: f-string: empty expression not allowed
Однако мы можем заполнить пустые фигурные скобки другими фигурными скобками.
print(f'А вот фигурные скобки: {{}}')
>>> А вот фигурные скобки: {}
Главная хитрость: выражения внутри «самых внутренних» фигурных скобок вычисляются только в том случае, если у нас нечётное количество пар этих скобок.
f'{{4 + 4}}' # две пары фигурных скобок, выражение не вычисляется
>>> '{4 + 4}'
f'{{{4 + 4}}}' # три пары скобок, выражение вычисляется
>>> '{8}'
Выравнивание и знаки после запятой
В форматированных строках можно указать количество десятичных знаков после запятой, количество символов, выделенных для вывода значения, а также выровнять значение по левому или правому краю. Общий синтаксис выглядит так:
f'{value:{width}.{precision}}'
Значение, двоеточие, затем ширина строки в фигурных скобках, точка, требуемая точность в фигурных скобках.
Для начала давайте посмотрим, как задать точность вывода значения.
pi = 3.14159265
print(f'{pi:.2f}')
>>> 3.
Если в параметре precision указать 2f, как здесь, то значение выводится с двумя знаками после запятой. Буква f в данном случае означает fractional part, то есть дробную часть числа. Если оставить просто 2, то значение целиком — и целая, и дробная часть — будет занимать два знака (точка не считается).
print(f'{pi:.2}')
>>> 3.1
Параметр width, стоящий в фигурных скобках после двоеточия и перед точкой, определяет ширину строки, выделенной под значение, и выравнивание в ней.
print(f'{5:<5}₽') # ширина 5 символов, выравниванием влево <
>>> 5 ₽
print(f'{5:>5}₽') # ширина 5 символов, выравниванием вправо >
>>> 5₽
Если не указать направление выравнивания (< или >), то строка по умолчанию будет выравниваться по левому краю (<).
Генерация списков, словарей и множеств
Генерация списков, словарей и множеств командами в одну строку — наиболее мощные и характерные фичи языка Python. Всё это великолепие работает и с форматированными строками. Вот список из форматированных строк, созданный на основе другого списка:
list_b = ['a', 'b', 'c', 'd']
[f'{x + x}' for x in list_b]
>>> ['aa', 'bb', 'cc', 'dd']
Форматированная строка может содержать и генератор списка, с этим проблем нет, — тогда она выдаст строку, состоящую из вычисленного списка, а не из команды генератора.
f'{[x + x for x in list_b]}'
>>> "['aa', 'bb', 'cc', 'dd']"
Со словарями и множествами дело обстоит чуть иначе — в основном из-за наличия фигурных скобок. Поэтому для того, чтобы строка была в виде словаря, а не в виде текста генератора, надо добавлять пробелы между внутренними и внешними фигурными скобками.
f"{{n: n**2 for n in range(5)}}" # выведет строку генератора
>>> '{n: n**2 for n in range(5)}'
f"{ {n: n**2 for n in range(5)} }" # добавили пробелы, сработало!
>>> '{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}'
f"{ {n**2 for n in range(3)} }" # генератор → множество → строка
>>> '{0, 1, 4}'
Заключение
Форматированная строка — скромный и не всегда заметный, но удобный и мощный инструмент в арсенале питониста. Используйте форматированные строки, если:
- вам важно, как выглядит вывод программы;
- вы хотите повысить читаемость вашего кода.
А также в любой другой непонятной ситуации.
На курсе «Профессия Python-разработчик» вы узнаете много других, не менее мощных фишек языка и станете по-настоящему продвинутым питонистом. Приходите!