Модуль 5 · Строки

Справочник по Python · модуль 5 · строки

Глава 5.6

5.6

Форматирование строк
и isalnum()

format() подставляет аргументы в шаблон, format_map() берёт значения из готового словаря, а спецификация после двоеточия задаёт ширину, точность и вид числа. isalnum() проверяет, состоит ли непустая строка только из букв и числовых символов.

Категория
Строковые методы
Уровень
Базовый → средний
Связанные темы
f-строки, словари, аргументы, Unicode
Зачем это знать
Строить текст из данных и проверять состав идентификатора

§1Шаблон отдельно от значений

Строку с подставленными значениями умеет собирать f-строка, знакомая с первого модуля. У неё есть одно ограничение: шаблон и значения записаны в одном месте и в один момент.

Схемакогда f-строка не подходит
f"Привет, {name}"      значения нужны здесь и сейчас

template = "Привет, {}"   шаблон можно хранить в переменной,
template.format(name)     файле настроек или словаре переводов

Отсюда и роль format(): он нужен, когда шаблон приходит откуда-то извне, а значения появляются позже. Типичные случаи — тексты сообщений в конфиге, переводы на разные языки, шаблоны писем.

§2format(): подстановка по порядку

Места подстановки обозначаются фигурными скобками. Пустые скобки заполняются аргументами по порядку.

main.pyдва поля, два аргумента
template = "Товар: {}, цена: {} ₽"
message = template.format("книга", 900)

print(message)
Выводготовая строка
Товар: книга, цена: 900 ₽

Число 900 подставилось без всякого str(): format() сам приводит аргументы к строке. Метод, как и все в этой главе, возвращает новую строку и не меняет шаблон — его можно использовать многократно.

§3Номер поля

Внутри скобок можно указать номер аргумента. Это позволяет менять порядок подстановки и использовать одно значение несколько раз.

main.pyполе 0 встречается дважды
template = "{0} изучает {1}. {0} пишет практику."
print(template.format("Макс", "Python"))
Выводимя подставлено два раза
Макс изучает Python. Макс пишет практику.

Нумерация начинается с нуля — как у индексов списка. Смешивать в одном шаблоне пустые скобки и номера нельзя.

main.pyавтоматическая и ручная нумерация вместе
print("{} {0}".format("a", "b"))
Ошибкадва способа в одном шаблоне
ValueError: cannot switch from automatic field numbering to manual field specification

§4Имя поля

Вместо номера удобнее указывать имя — тогда шаблон читается сам по себе, без сверки с порядком аргументов.

main.pyименованные аргументы
template = "{name}: {score} баллов"
print(template.format(name="Анна", score=95))
Выводпорядок аргументов больше не важен
Анна: 95 баллов

Для шаблона, который правит не программист — переводчик или редактор, — именованные поля единственно разумный вариант: перепутать {name} и {score} местами безопасно, а {0} и {1} — нет.

§5Спецификация формата

После двоеточия внутри скобок указывают, как показать значение. Это отдельный мини-язык, общий для format() и f-строк.

Схемаустройство поля подстановки
{name:>10.2f}
 │    │ │ │ └ тип: f — дробное, d — целое, s — строка
 │    │ │ └ точность: два знака после запятой
 │    │ └ ширина: минимум 10 позиций
 │    └ выравнивание: < влево, > вправо, ^ по центру
 └ имя или номер поля

Все части необязательны и записываются именно в этом порядке.

main.pyширина с точностью и проценты
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, — но прямо внутри шаблона.

main.pyтри направления выравнивания
print("|{:<10}|".format("лево"))
print("|{:>10}|".format("право"))
print("|{:^10}|".format("центр"))
Выводширина поля — десять позиций
|лево      |
|     право|
|  центр   |

Разница с методами главы 5.3 в том, что здесь ширина задаётся вместе с текстом шаблона, а не отдельным вызовом. Для таблицы из нескольких колонок это заметно короче.

§7Форматы для чисел

Чаще всего спецификация нужна именно для чисел — привести их к читаемому виду.

main.pyчетыре типичных случая
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Двойные скобки

Раз фигурные скобки означают поле подстановки, вывести саму скобку можно только удвоением.

main.pyлитеральные скобки вокруг значения
print("Настройки: {{theme: {}}}".format("dark"))
Выводвнешние скобки полями не стали
Настройки: {theme: dark}

То же правило действует и в f-строках. Оно чаще всего нужно, когда программа сама печатает код, JSON или шаблон.

§9format_map(): словарь целиком

Если значения уже собраны в словарь, их не нужно перечислять по одному — format_map() принимает словарь как есть.

main.pyключи словаря совпадают с именами полей
user = {"name": "Макс", "role": "teacher"}
template = "{name} — {role}"

print(template.format_map(user))
Выводоба поля заполнены
Макс — teacher

Имена полей в шаблоне должны совпадать с ключами словаря. Словари разбирались в главе 4.2.

§10format_map() или format(**data)

Тот же результат даёт распаковка словаря из главы 6.6.

main.pyдве записи, один результат
user = {"name": "Макс", "role": "teacher"}

print("{name} — {role}".format_map(user))
print("{name} — {role}".format(**user))
Выводстроки совпали
Макс — teacher
Макс — teacher
ЗаписьЧто происходит со словарём
format_map(data)передаётся напрямую, копия не создаётся
format(**data)распаковывается в отдельные аргументы

Для обычного словаря разница незаметна. Она проявляется на больших словарях, где лишняя распаковка стоит времени, и на словарях с особым поведением при отсутствии ключа — о них следующий параграф.

§11Отсутствующий ключ

Если в словаре нет ключа, названного в шаблоне, форматирование прерывается.

main.pyполя age в словаре нет
template = "{name}, {age}"
print(template.format_map({"name": "Макс"}))
Ошибкане хватает данных
KeyError: 'age'

Это тот же KeyError, что при обращении user["age"] из главы 4.2. Обычное решение — заполнить недостающие ключи заранее, воспользовавшись методом get() или подготовив словарь со значениями по умолчанию.

Словарь, который не падает

Главное преимущество format_map() перед format(**data) в том, что ему можно передать словарь с собственным поведением для отсутствующих ключей — например, подставляющий прочерк вместо ошибки. Такие словари создают через наследование, и это тема модуля 9.

§12f-строка или format()

Для локальной сборки строки f-строка короче и читается лучше: значения видны прямо в тексте.

main.pyодинаковый результат
name = "Макс"
score = 91

print(f"{name}: {score}")
print("{}: {}".format(name, score))
Выводдве одинаковые строки
Макс: 91
Макс: 91
СитуацияЧто выбрать
значения рядом, в тех же строках кодаf-строка
шаблон хранится в файле или переменнойformat()
значения уже лежат в словареformat_map()
шаблон приходит от пользователяни то ни другое — это опасно

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

§13isalnum(): состав строки

Метод возвращает True, если строка непуста и все её символы — буквы или числовые знаки.

main.pyтри похожие строки
print("Python312".isalnum())
print("Python 312".isalnum())
print("Python-312".isalnum())
Выводпробел и дефис не подходят
True
False
False

Условие проверяется для каждого символа: один неподходящий делает результат ложным. Пустая строка тоже даёт False — «все символы подходят» не считается выполненным, когда символов нет вовсе.

§14isalnum() и Unicode

Метод работает со всем Unicode, а не только с латиницей и цифрами 0–9.

main.pyкириллица, арабские цифры, пустая строка
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, — а значит, для проверки логина его одного мало.

Глава 5.6 · Форматирование строк · Справочник по Python Автор: Макаров Максим Николаевич