Как подставлять переменные в строку с форматированием в Python
Что проверяют
Базу языка и то, знаете ли вы, где форматирование строк опасно. Для дата-специальностей следом почти всегда спрашивают, можно ли собирать SQL-запрос через f-строку и как форматировать числа в отчётах.
Как отвечать
Назовите три способа и порядок предпочтения:
- f-строки: основной вариант с Python 3.6,
f"{name}: {score:.3f}". Внутри можно писать выражения и вызовы. С 3.8 есть отладочная формаf"{x=}", которая печатает имя и значение, а с 3.12 внутри можно использовать те же кавычки, что снаружи; str.format(): полезен, когда шаблон хранится отдельно от данных, в конфиге или словаре текстов:template.format(**row);- оператор
%: старый стиль, живёт в легаси и в модулеlogging.
Покажите мини-язык спецификаций формата, он общий для f-строк и format():
- числа:
:.2fдва знака,:,разделитель тысяч,:.1%процент,:eэкспонента; - выравнивание:
:>10,:<10,:^10,:08.3fс ведущими нулями; - преобразование:
!rвызываетrepr(), в логах так видны кавычки и лишние пробелы.
Два правила отличают сильный ответ. В logging передавайте аргументы отдельно, logger.info("rows=%d", n): строка соберётся, только если уровень лога включён. В SQL никаких f-строк: параметры передаются драйверу через cursor.execute(sql, params) или через text() с именованными параметрами в SQLAlchemy.
Можно упомянуть t-строки из Python 3.14: они возвращают не готовую строку, а шаблон с отдельными значениями, и библиотека сама решает, как их экранировать.
Где спотыкаются
Собирают SQL или команду оболочки через f-строку. Это прямой путь к инъекции, даже если данные кажутся «своими».
Называют str.format() устаревшим. Он не устарел, у него другая ниша: подстановка в заранее известный шаблон, который хранится отдельно.
Путают округление при выводе с округлением значения. f"{x:.2f}" меняет только текст, а в датафрейме остаётся полная точность; для денег нужны Decimal или целые копейки.