f-строка подставляет значение прямо в текст. Буква f перед кавычками включает режим, в котором фигурные скобки перестают быть обычными символами и становятся местом для выражения. Всё, что внутри скобок, вычисляется и превращается в текст. Код выполнен на CPython 3.14.5.
Выражения становятся частью строки
{...} вычисляется отдельно, затем результаты вставляются в обычный текст.Как работает 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 под вывод отведён отдельный пак: сначала подстановка значений, потом выравнивание колонок, потом сборка отчёта. Проверить себя можно на форматировании длительности, где формат выбирается по величине входного числа.