f-строки в Python: форматирование и вывод чисел

Python Автор: Среда и версия: CPython 3.14.5
содержание

f-строка подставляет значение прямо в текст. Буква f перед кавычками включает режим, в котором фигурные скобки перестают быть обычными символами и становятся местом для выражения. Всё, что внутри скобок, вычисляется и превращается в текст. Код выполнен на CPython 3.14.5.

Python / 01

Выражения становятся частью строки

Выражения становятся частью строки01 Данные name = "Аня" count = 3 Переменные уже имеют значения. 02 Подстановка f"{name}: {count} заказа" Каждое выражение в фигурных скобках вычисляется. 03 Результат Аня: 3 заказа Получилась обычная строка str.01Данныеname = "Аня"count = 3Переменные уже имеют значения.02Подстановкаf"{name}: {count} заказа"Каждое выражение в фигурных скобках вычисляется.03РезультатАня: 3 заказаПолучилась обычная строка str.
Каждое выражение в {...} вычисляется отдельно, затем результаты вставляются в обычный текст.

Как работает f-строка

Буква перед кавычкой, имя переменной в скобках:

name = "Аня"
orders = 3
print(f"{name} сделала {orders} заказа")
Аня сделала 3 заказа

Забыть букву f — самая частая ошибка, и Python о ней не сообщает. Строка просто печатается как есть:

name = "Аня"
orders = 3
print("{name} сделала {orders} заказа")
{name} сделала {orders} заказа

Ни ошибки, ни предупреждения. Увидел в выводе фигурные скобки, проверь букву перед кавычкой.

Что можно писать внутри скобок

Любое выражение, а не только имя переменной: арифметику, вызов метода, обращение по индексу, сравнение.

price = 1200
qty = 3
name = "Аня"
cities = ["Москва", "Казань"]
print(f"итого {price * qty} рублей")
print(f"имя заглавными: {name.upper()}")
print(f"первый город: {cities[0]}, всего {len(cities)}")
print(f"скидка есть: {price > 1000}")
итого 3600 рублей
имя заглавными: АНЯ
первый город: Москва, всего 2
скидка есть: True

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

Как округлить число и выровнять колонку

После двоеточия внутри скобок идёт формат. Точка с числом задаёт знаки после запятой:

avg = 1166.6666666
print(f"{avg:.2f}")
print(f"{avg:.0f}")
print(f"{avg:.4f}")
1166.67
1167
1166.6667

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

total = 1234567.891
print(f"{total:,.2f}")
print(f"{total:_.2f}")
1,234,567.89
1_234_567.89

Число перед точкой задаёт ширину поля, а знаки <, > и ^ — выравнивание. Так собирают таблицу без всяких библиотек:

rows = [("Москва", 4100), ("Казань", 1700), ("Сочи", 500)]
for city, amount in rows:
    print(f"{city:<10}|{amount:>8}")
Москва    |    4100
Казань    |    1700
Сочи      |     500

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

print(f"{'итого':*^20}")
print(f"{42:08.2f}")
print(f"{42:+d} {-42:+d}")
*******итого********
00042.00
+42 -42

Проценты умеет считать сам формат: он умножает на 100 и дописывает знак.

share = 0.1734
print(f"{share:.1%}")
17.3%

Ширину можно взять из переменной, вложив ещё одни скобки. Это удобно, когда колонку подгоняют под самое длинное значение:

width = 12
print(f"{'Москва':>{width}}|")
      Москва|

Как превратить число в строку

Три способа дают одинаковый результат:

n = 42
print(str(n), f"{n}", "{}".format(n), sep=" | ")
print(type(str(n)).__name__, type(f"{n}").__name__)
42 | 42 | 42
str str

str() берут, когда нужно только преобразование и ничего больше. f-строку берут, когда число вставляется в текст. Разницы в типе нет, на выходе обычная строка в обоих случаях.

Обратное преобразование делают int() и float(), и вот там ошибка возможна:

print(int("42"), float("3.14"))
try:
    int("42.5")
except ValueError as exc:
    print(f"ValueError: {exc}")
42 3.14
ValueError: invalid literal for int() with base 10: '42.5'

int() не разбирает дробную часть даже в виде текста. Для строки с точкой сначала идёт float(), а уже потом int(), если целое действительно нужно.

Отладочная запись со знаком равенства

Если после выражения поставить =, f-строка напечатает и само выражение, и его значение:

balance = 1000
name = "Аня"
print(f"{balance=}")
print(f"{balance * 2=}")
print(f"{name=}")
balance=1000
balance * 2=2000
name='Аня'

Это готовая замена отладочному print. Имя не разъедется со значением при переименовании, а на последней строке видно ещё одну деталь: значение показано с кавычками, потому что = включает представление объекта, а не его текст.

Тот же эффект даёт суффикс !r без знака равенства:

text = "Аня"
print(f"{text}")
print(f"{text!r}")
Аня
'Аня'

Разница видна на строках с пробелами по краям: !r покажет кавычки и сделает лишние пробелы заметными.

Кавычки и фигурные скобки внутри

Чтобы напечатать саму фигурную скобку, её удваивают:

name = "Аня"
print(f"{{это не подстановка}}, а {name} — подстановка")
{это не подстановка}, а Аня — подстановка

Кавычки внутри выражения раньше приходилось брать другого вида, чем снаружи. Начиная с Python 3.12 работают оба варианта:

data = {"город": "Москва"}
print(f"город: {data['город']}")
print(f"город: {data["город"]}")
город: Москва
город: Москва

Вторая строка на Python 3.11 и старше упала бы с синтаксической ошибкой. Если код должен работать и там, кавычки по-прежнему чередуют.

Чем f-строка отличается от format и %

Тремя вещами: она короче, вычисляется на месте и не разъезжается с аргументами.

name, orders = "Аня", 3
old_pct = "%s сделала %d заказа" % (name, orders)
old_fmt = "{} сделала {} заказа".format(name, orders)
new_f = f"{name} сделала {orders} заказа"
print(old_pct == old_fmt == new_f)
True

Результат один, разница в надёжности. В первых двух формах значения перечислены отдельно от текста, поэтому их легко перепутать местами или потерять при правке. f-строка ставит значение туда, где оно читается.

У .format() осталась одна ниша: шаблон, который заполняют позже. f-строка вычисляется сразу и для отложенного использования не годится.

template = "{who} сделала {n} заказа"
print(template.format(who="Аня", n=3))
Аня сделала 3 заказа

Форма с % считается устаревшей, но встречается в старом коде и в логировании, где у неё своя причина: logging откладывает подстановку до момента, когда сообщение действительно понадобится.

Ошибки, на которых спотыкаются

Формат не подходит типу. Числовой формат к строке не применить:

name = "Аня"
try:
    print(f"{name:.2f}")
except ValueError as exc:
    print(f"ValueError: {exc}")
ValueError: Unknown format code 'f' for object of type 'str'

Сообщение называет и код формата, и тип, поэтому причина видна сразу: под .2f подставили текст.

Логика внутри строки. f"{'да' if ok else 'нет'}" работает, но читается тяжело, а при двух условиях превращается в ребус. Значение считают заранее.

Форматирование длительности вручную. Секунды в вид M:SS собирают арифметикой, а не форматом, и это отдельная задача. Даты форматируются своим мини-языком через datetime: f"{d:%d.%m.%Y}".

f-строка вместо запроса к базе. Подставлять значение в SQL через f-строку опасно: так получается инъекция. Параметры передают драйверу отдельно, а не склеивают текст запроса.

Частые вопросы

Как вывести число с двумя знаками после запятой

f"{value:.2f}". Округление математическое, поэтому 1166.6666 станет 1166.67, а не 1166.66.

Как вставить переменную в строку

f"текст {переменная} текст". Буква f перед кавычкой обязательна, иначе скобки останутся в выводе как есть.

Как сделать перенос строки внутри f-строки

Символом \n внутри текста или тройными кавычками для многострочного литерала. Соседние строковые литералы в скобках склеиваются сами, поэтому длинный отчёт удобно собирать столбиком из нескольких f-строк.

Можно ли использовать f-строки в старом Python

Начиная с версии 3.6. Отладочный = появился в 3.8, а одинаковые кавычки внутри и снаружи — только в 3.12.

Что учить дальше

Форматирование почти всегда идёт рядом со сборкой текста из списка через join и с перебором данных циклом. В пути «Python с нуля» на Koddo под вывод отведён отдельный пак: сначала подстановка значений, потом выравнивание колонок, потом сборка отчёта. Проверить себя можно на форматировании длительности, где формат выбирается по величине входного числа.

Источники