Справочник по Python · модуль 5 · строки
Глава 5.6
Форматирование строк
и isalnum()
format() подставляет аргументы в шаблон, format_map() берёт значения из готового словаря, а спецификация после двоеточия задаёт ширину, точность и вид числа. isalnum() проверяет, состоит ли непустая строка только из букв и числовых символов.
- Категория
- Строковые методы
- Уровень
- Базовый → средний
- Связанные темы
- f-строки, словари, аргументы, Unicode
- Зачем это знать
- Строить текст из данных и проверять состав идентификатора
§1Шаблон отдельно от значений
Строку с подставленными значениями умеет собирать f-строка, знакомая с первого модуля. У неё есть одно ограничение: шаблон и значения записаны в одном месте и в один момент.
f"Привет, {name}" значения нужны здесь и сейчас
template = "Привет, {}" шаблон можно хранить в переменной,
template.format(name) файле настроек или словаре переводов
Отсюда и роль format(): он нужен, когда шаблон приходит откуда-то извне, а значения появляются позже. Типичные случаи — тексты сообщений в конфиге, переводы на разные языки, шаблоны писем.
§2format(): подстановка по порядку
Места подстановки обозначаются фигурными скобками. Пустые скобки заполняются аргументами по порядку.
template = "Товар: {}, цена: {} ₽" message = template.format("книга", 900) print(message)
Товар: книга, цена: 900 ₽
Число 900 подставилось без всякого str(): format() сам приводит аргументы к строке. Метод, как и все в этой главе, возвращает новую строку и не меняет шаблон — его можно использовать многократно.
§3Номер поля
Внутри скобок можно указать номер аргумента. Это позволяет менять порядок подстановки и использовать одно значение несколько раз.
template = "{0} изучает {1}. {0} пишет практику." print(template.format("Макс", "Python"))
Макс изучает Python. Макс пишет практику.
Нумерация начинается с нуля — как у индексов списка. Смешивать в одном шаблоне пустые скобки и номера нельзя.
print("{} {0}".format("a", "b"))
ValueError: cannot switch from automatic field numbering to manual field specification
§4Имя поля
Вместо номера удобнее указывать имя — тогда шаблон читается сам по себе, без сверки с порядком аргументов.
template = "{name}: {score} баллов" print(template.format(name="Анна", score=95))
Анна: 95 баллов
Для шаблона, который правит не программист — переводчик или редактор, — именованные поля единственно разумный вариант: перепутать {name} и {score} местами безопасно, а {0} и {1} — нет.
§5Спецификация формата
После двоеточия внутри скобок указывают, как показать значение. Это отдельный мини-язык, общий для format() и f-строк.
{name:>10.2f}
│ │ │ │ └ тип: f — дробное, d — целое, s — строка
│ │ │ └ точность: два знака после запятой
│ │ └ ширина: минимум 10 позиций
│ └ выравнивание: < влево, > вправо, ^ по центру
└ имя или номер поля
Все части необязательны и записываются именно в этом порядке.
price = 1234.5 ratio = 0.873 print("Цена: {:10.2f}".format(price)) print("Готово: {:.1%}".format(ratio))
Цена: 1234.50 Готово: 87.3%
Тип % не просто дописывает знак процента: он умножает значение на 100. Поэтому 0.873 превращается в 87.3%.
§6Ширина и выравнивание
Эта часть спецификации решает ту же задачу, что ljust(), rjust() и center() из главы 5.3, — но прямо внутри шаблона.
print("|{:<10}|".format("лево")) print("|{:>10}|".format("право")) print("|{:^10}|".format("центр"))
|лево | | право| | центр |
Разница с методами главы 5.3 в том, что здесь ширина задаётся вместе с текстом шаблона, а не отдельным вызовом. Для таблицы из нескольких колонок это заметно короче.
§7Форматы для чисел
Чаще всего спецификация нужна именно для чисел — привести их к читаемому виду.
print("{:,}".format(1234567)) print("{:.3f}".format(2 / 3)) print("{:+d}".format(5)) print("{:05d}".format(42))
1,234,567 0.667 +5 00042
| Запись | Что делает | Пример результата |
|---|---|---|
{:,} | разделяет тысячи запятыми | 1,234,567 |
{:.3f} | три знака после запятой | 0.667 |
{:+d} | всегда показывает знак | +5 |
{:05d} | дополняет нулями до ширины | 00042 |
{:.1%} | проценты с одним знаком | 87.3% |
Округление через {:.2f} относится только к показу: само число не меняется. Это та же логика, что у round() из главы 1.9, но применённая к выводу.
§8Двойные скобки
Раз фигурные скобки означают поле подстановки, вывести саму скобку можно только удвоением.
print("Настройки: {{theme: {}}}".format("dark"))
Настройки: {theme: dark}То же правило действует и в f-строках. Оно чаще всего нужно, когда программа сама печатает код, JSON или шаблон.
§9format_map(): словарь целиком
Если значения уже собраны в словарь, их не нужно перечислять по одному — format_map() принимает словарь как есть.
user = {"name": "Макс", "role": "teacher"}
template = "{name} — {role}"
print(template.format_map(user))
Макс — teacher
Имена полей в шаблоне должны совпадать с ключами словаря. Словари разбирались в главе 4.2.
§10format_map() или format(**data)
Тот же результат даёт распаковка словаря из главы 6.6.
user = {"name": "Макс", "role": "teacher"}
print("{name} — {role}".format_map(user))
print("{name} — {role}".format(**user))
Макс — teacher Макс — teacher
| Запись | Что происходит со словарём |
|---|---|
format_map(data) | передаётся напрямую, копия не создаётся |
format(**data) | распаковывается в отдельные аргументы |
Для обычного словаря разница незаметна. Она проявляется на больших словарях, где лишняя распаковка стоит времени, и на словарях с особым поведением при отсутствии ключа — о них следующий параграф.
§11Отсутствующий ключ
Если в словаре нет ключа, названного в шаблоне, форматирование прерывается.
template = "{name}, {age}" print(template.format_map({"name": "Макс"}))
KeyError: 'age'
Это тот же KeyError, что при обращении user["age"] из главы 4.2. Обычное решение — заполнить недостающие ключи заранее, воспользовавшись методом get() или подготовив словарь со значениями по умолчанию.
Главное преимущество format_map() перед format(**data) в том, что ему можно передать словарь с собственным поведением для отсутствующих ключей — например, подставляющий прочерк вместо ошибки. Такие словари создают через наследование, и это тема модуля 9.
§12f-строка или format()
Для локальной сборки строки f-строка короче и читается лучше: значения видны прямо в тексте.
name = "Макс" score = 91 print(f"{name}: {score}") print("{}: {}".format(name, score))
Макс: 91 Макс: 91
| Ситуация | Что выбрать |
|---|---|
| значения рядом, в тех же строках кода | f-строка |
| шаблон хранится в файле или переменной | format() |
| значения уже лежат в словаре | format_map() |
| шаблон приходит от пользователя | ни то ни другое — это опасно |
Последняя строка важна: шаблон, полученный извне, — это исполняемая инструкция, и через неё можно добраться до данных программы. Форматировать чужие шаблоны без специальной подготовки не следует.
§13isalnum(): состав строки
Метод возвращает True, если строка непуста и все её символы — буквы или числовые знаки.
print("Python312".isalnum()) print("Python 312".isalnum()) print("Python-312".isalnum())
True False False
Условие проверяется для каждого символа: один неподходящий делает результат ложным. Пустая строка тоже даёт False — «все символы подходят» не считается выполненным, когда символов нет вовсе.
§14isalnum() и Unicode
Метод работает со всем Unicode, а не только с латиницей и цифрами 0–9.
print("Курс2026".isalnum()) print("مرحبا١٢٣".isalnum()) print("".isalnum())
True True False
Более того, «числовым символом» считаются и такие знаки, как дробь ½ или римская цифра Ⅻ, — обе строки дадут True. Подробности о разнице между isdigit(), isdecimal() и isnumeric() — в главе 5.7.
§15Чего isalnum() не проверяет
Метод часто пытаются использовать для проверки логина или идентификатора, и здесь его легко понять неправильно.
| Строка | isalnum() | Почему |
|---|---|---|
"user_name" | False | подчёркивание не буква и не цифра |
"Курс2026" | True | кириллица тоже буквы |
"½" | True | дробь считается числовым символом |
"" | False | требуется хотя бы один символ |
Если нужен именно формат «латиница и цифры», isalnum() недостаточно: он пропустит и кириллицу, и экзотические числовые знаки. Для проверки имени переменной есть отдельный метод isidentifier() из главы 5.7 — он как раз разрешает подчёркивание.
§16Частые ошибки
| Что написано | Что произойдёт | Как правильно |
|---|---|---|
"{} {0}".format(a, b) | ValueError: смешаны два вида нумерации | только {} или только номера |
"{age}".format_map(user) без ключа | KeyError | заполнить недостающие ключи заранее |
одинарные скобки для вывода { | они будут приняты за поле подстановки | писать {{ и }} |
"{:2f}" вместо "{:.2f}" | это ширина 2, а не два знака после запятой | точность пишется после точки |
template.format(...) без сохранения | результат выброшен: строки неизменяемы | сохранить или сразу использовать |
| форматировать шаблон от пользователя | через шаблон доступны данные программы | не подставлять чужие шаблоны |
"user_name".isalnum() | False из-за подчёркивания | isidentifier() или своя проверка |
| считать пустую строку буквенно-цифровой | isalnum() вернёт False | нужен хотя бы один символ |
§17Проверьте себя
Когда format() нужнее f-строки?
Когда шаблон хранится отдельно от значений — в переменной, файле настроек или словаре переводов.
Почему "{} {0}".format(a, b) вызывает ошибку?
В одном шаблоне нельзя смешивать автоматическую нумерацию полей и явные номера.
Что означает {:10.2f}?
Минимальная ширина поля — десять позиций, два знака после запятой, тип — дробное число.
Как вывести фигурную скобку внутри шаблона?
Удвоить её: {{ или }}. То же правило работает в f-строках.
Чем format_map() отличается от format(**data)?
Словарь передаётся напрямую, без распаковки. Это позволяет использовать словари с собственным поведением при отсутствии ключа.
Вернёт ли "abc_123".isalnum() значение True?
Нет: подчёркивание не относится ни к буквам, ни к числовым символам.
§18Шпаргалка
"{}".format(value)"{0} и {0}".format(x)"{name}".format(name=x)"{name}".format_map(data)"{:.2f}""{:>10}""{{"text.isalnum()Итог главы
format() подставляет позиционные и именованные аргументы в шаблон, который может храниться отдельно от данных, — это его главное отличие от f-строки. Спецификация после двоеточия задаёт ширину, выравнивание, точность и вид числа, и тот же язык работает внутри f-строк. format_map() принимает готовый словарь целиком. isalnum() проверяет, что строка непуста и состоит только из букв и числовых символов Unicode, — а значит, для проверки логина его одного мало.