W3docs

Форматирование строк в Python

Три метода форматирования строк в Python: оператор %, str.format() и f-строки — с примерами для чисел, выравнивания, дат и не только.

Форматирование строк позволяет динамически создавать строки, вставляя переменные, выражения и вычисленные значения в шаблон. Python предлагает три различных подхода: устаревший оператор %, универсальный метод str.format() и современный синтаксис f-строк — каждый со своими преимуществами и подходящими сценариями использования.

В этой главе рассматриваются:

  • Когда и почему использовать каждый метод форматирования
  • Оператор % (устаревший, но всё ещё распространён в логах и старых кодовых базах)
  • str.format() с позиционными и именованными плейсхолдерами
  • f-строки (рекомендуемый современный подход)
  • Спецификаторы формата: ширина, выравнивание, точность, заполнение, знак и основание системы счисления
  • Форматирование чисел, процентов, дат и времени
  • Распространённые ловушки и пограничные случаи

Подробное описание f-строк — включая выражения, условную логику и улучшения Python 3.12 — см. в главе Python f-Strings.

Какой метод использовать?

МетодВерсия PythonКогда использовать
Оператор %2.x / 3.xУстаревший код, модуль logging, очень простые подстановки
str.format()2.6+Когда нужны многократно используемые строки формата или именованные аргументы
f-строки3.6+Новый код — самые быстрые, наиболее читаемые, поддерживают встроенные выражения

Если вы не поддерживаете код на Python 2 или старой версии Python 3, используйте f-строки. Они вычисляются во время выполнения, не создают дополнительных накладных расходов на вызов и держат имя переменной рядом с тем местом, где оно появляется в строке.

Оператор % (устаревшее форматирование)

Оператор % подставляет значения в строку формата, используя спецификаторы преобразования в стиле C.

Распространённые спецификаторы преобразования:

СпецификаторЗначение
%sСтрока (вызывает str() для значения)
%dЗнаковое целое число
%fЧисло с плавающей точкой
%rrepr() значения
%%Символ %
python— editable, runs on the server

Ширина и точность с %

Ширину поля и точность десятичного представления можно указать прямо в спецификаторе:

pi = 3.14159265
print("%10.3f" % pi)   # right-aligned in a 10-char field, 3 decimal places
#      3.142
print("%-10.3f|" % pi) # left-aligned
# 3.142     |
print("%010.3f" % pi)  # zero-padded
# 000003.142

Ловушка: одиночное значение против кортежа

При подстановке одного значения безопаснее передавать его в кортеже:

value = "hello"
# Risky — if value were itself a tuple, this would fail:
# print("Got: %s" % value)

# Safe:
print("Got: %s" % (value,))
# Got: hello

str.format() — гибкое форматирование с плейсхолдерами

Метод str.format() пришёл на смену оператору % в Python 2.6+. В качестве плейсхолдеров он использует {} и поддерживает позиционные, индексированные и именованные аргументы.

Позиционные и индексированные плейсхолдеры

python— editable, runs on the server

Именованные (keyword) плейсхолдеры

python— editable, runs on the server

Именованные плейсхолдеры делают строки формата самодокументированными и особенно удобны, когда одно и то же значение встречается несколько раз или когда строка формата берётся из файла конфигурации.

Повторное использование строк формата

Поскольку str.format() принимает строку на вход, шаблон можно сохранить в переменной и использовать повторно:

template = "Hello, {name}! You have {count} new messages."
print(template.format(name="Alice", count=3))
print(template.format(name="Bob", count=0))
# Hello, Alice! You have 3 new messages.
# Hello, Bob! You have 0 new messages.

f-строки — современное форматирование в Python

f-строки (форматированные строковые литералы) добавляют перед строкой префикс f или F и вычисляют любое выражение внутри {} во время выполнения. Они доступны начиная с Python 3.6 и являются рекомендуемым подходом для нового кода.

name = "John"
age = 25
print(f"My name is {name} and I am {age} years old.")
# My name is John and I am 25 years old.

f-строки поддерживают любые допустимые выражения Python внутри фигурных скобок — арифметику, вызовы методов, условные выражения и многое другое:

items = ["apple", "banana", "cherry"]
print(f"Cart has {len(items)} items. First: {items[0].upper()}.")
# Cart has 3 items. First: APPLE.

x = -7
print(f"Absolute value: {abs(x)}")
# Absolute value: 7

Полное руководство, включая отладку с =, многострочные f-строки и улучшения Python 3.12, см. в главе Python f-Strings.

Спецификаторы формата: мини-язык

И str.format(), и f-строки используют один и тот же мини-язык спецификации формата внутри {} после двоеточия:

{[field_name]:[fill][align][sign][#][0][width][grouping][.precision][type]}

В таблице ниже приведены наиболее полезные параметры:

ПараметрСимволЭффект
Выравнивание< > ^По левому краю, по правому краю, по центру
Заполнениелюбой символЗаполняет отступ (используется вместе с выравниванием и шириной)
Знак+ - Показывать + для положительных; только минус по умолчанию; пробел для положительных
Префикс#0x для шестнадцатеричного, 0o для восьмеричного, 0b для двоичного
Дополнение нулями0Заполнение нулями вместо пробелов
Ширинацелое числоМинимальная ширина поля
Разделитель групп, или _Разделитель тысяч
Точность.nКоличество знаков после запятой (для чисел с плавающей точкой) или максимальное число символов (для строк)
Типd f e g x o b %Целое, число с плавающей точкой, научная нотация, общий формат, шестнадцатеричный, восьмеричный, двоичный, проценты

Выравнивание и ширина

text = "hello"
print(f"{text:<10}|")   # left-aligned in 10-char field
# hello     |
print(f"{text:>10}|")   # right-aligned
#      hello|
print(f"{text:^10}|")   # centered
#   hello   |
print(f"{text:*^10}|")  # centered, filled with *
# **hello***|

Те же спецификаторы выравнивания работают с str.format(). Вот пример, совмещающий выравнивание и точность:

python— editable, runs on the server

Форматирование чисел

x = 123.456789

print(f"{x:.2f}")        # two decimal places
# 123.46

print(f"{x:,.2f}")       # thousands separator, two decimal places
# 123.46

print(f"{x:+.2f}")       # explicit plus sign for positive numbers
# +123.46

print(f"{x:10.2f}")      # right-aligned in a 10-char field
#     123.46

print(f"{x:<10.2f}|")    # left-aligned
# 123.46    |

print(f"{x:010.2f}")     # zero-padded to 10 characters
# 0000123.46

Большие числа и проценты

population = 8_100_000_000
print(f"{population:,}")    # comma separator
# 8,100,000,000

print(f"{population:_}")    # underscore separator (Python 3.6+)
# 8_100_000_000

ratio = 0.8567
print(f"{ratio:.1%}")       # percentage, one decimal place
# 85.7%

Основания систем счисления

n = 255
print(f"{n:d}")   # decimal (default)
# 255
print(f"{n:x}")   # lowercase hexadecimal
# ff
print(f"{n:X}")   # uppercase hexadecimal
# FF
print(f"{n:#x}")  # hex with 0x prefix
# 0xff
print(f"{n:o}")   # octal
# 377
print(f"{n:b}")   # binary
# 11111111
print(f"{n:#b}")  # binary with 0b prefix
# 0b11111111

Те же спецификаторы можно использовать с str.format():

python— editable, runs on the server

Научная нотация

avogadro = 6.02214076e23
print(f"{avogadro:.3e}")   # scientific notation, 3 decimal places
# 6.022e+23

print(f"{avogadro:.3E}")   # uppercase E
# 6.022E+23

print(f"{avogadro:.3g}")   # general: compact form, removes trailing zeros
# 6.02e+23

Форматирование строк с format() и f-строками

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

python— editable, runs on the server

Спецификаторы для строк позволяют управлять усечением и дополнением:

s = "Python"
print(f"{s:.3}")      # truncate to 3 characters
# Pyt

print(f"{s:10}")      # pad to width 10 (left-aligned by default for strings)
# Python    

print(f"{s:>10}")     # right-aligned
#     Python

print(f"{s:*^12}")    # centered, filled with *
# ***Python***

Форматирование дат и времени

При форматировании объектов datetime в f-строках или str.format() используйте коды формата strftime внутри фигурных скобок:

import datetime

date = datetime.datetime(2024, 3, 15, 10, 30, 0)

# Default string representation
print(f"Default: {date}")
# Default: 2024-03-15 10:30:00

# strftime codes inside the format spec
print(f"Formatted: {date:%B %d, %Y}")
# Formatted: March 15, 2024

print(f"Time only: {date:%H:%M:%S}")
# Time only: 10:30:00

print(f"ISO-style: {date:%Y-%m-%d}")
# ISO-style: 2024-03-15

Тот же синтаксис работает с str.format():

import datetime
date = datetime.datetime(2024, 3, 15, 10, 30, 0)
print("The date is {:%B %d, %Y}".format(date))
# The date is March 15, 2024

Дополнительные техники форматирования дат см. в главе Python Modify Strings, посвящённой методам работы со строками.

Продвинутые техники

Вложенные выражения в f-строках

f-строки позволяют вычислять спецификатор формата динамически:

width = 10
precision = 3
value = 3.14159

print(f"{value:{width}.{precision}f}")
# output:      3.142  (right-aligned in a 10-char field, 3 decimal places)

Спецификатор формата с format() и переменными

Та же техника работает с str.format() при помощи вложенных {}:

width = 8
print("{:{width}}".format("left", width=width))
# left    

Условное форматирование в f-строках

Поскольку f-строки вычисляют любое выражение, внутри них можно использовать условные выражения:

score = 73
label = f"{'pass' if score >= 60 else 'fail'}"
print(f"Score {score}: {label}")
# Score 73: pass

Отладка с = (Python 3.8+)

Добавьте = внутри f-строки, чтобы вывести и выражение, и его значение — очень удобно для отладки:

x = 42
y = x * 2
print(f"{x=}, {y=}")
# x=42, y=84

Распространённые ловушки

1. Экранирование фигурных скобок. Чтобы включить в форматированную строку буквальный символ { или }, удвойте его:

print(f"Use {{curly braces}} in f-strings")
# Use {curly braces} in f-strings

2. Кавычки внутри f-строк. В Python 3.11 и ранее выражение внутри {} не может использовать тот же тип кавычек, что и внешняя f-строка:

names = ["Alice", "Bob"]
# Wrong in Python <= 3.11:
# print(f"First: {names[0].upper()}")  -- this is fine
# print(f"{'Alice'.upper()}")          -- single quotes inside double-quoted f-string is fine
# But nesting the same quotes fails:
# print(f"{names["Alice"]}")           -- SyntaxError in <= 3.11

# Safe approach for <= 3.11:
key = "Alice"
print(f"{key.upper()}")
# ALICE

3. Ловушка с кортежем при %. При использовании форматирования % с одиночным значением, которое само является кортежем, оберните его:

coords = (10, 20)
# This raises TypeError because % sees a 2-element tuple:
# print("Position: %s" % coords)

# Fix: wrap in a 1-element tuple
print("Position: %s" % (coords,))
# Position: (10, 20)

4. str.format() и безопасность. Никогда не передавайте ненадёжный пользовательский ввод в качестве строки формата для str.format() — вредоносный шаблон может получить доступ к атрибутам объектов и привести к утечке данных. f-строки всегда являются жёстко заданными строками в коде, поэтому они не подвержены этой уязвимости.

Практическое сравнение

Вот одинаковый вывод, созданный всеми тремя методами бок о бок:

item = "widget"
qty = 42
unit_price = 4.5

# % operator
print("%-12s %4d  $%7.2f" % (item, qty, unit_price))

# str.format()
print("{:<12} {:>4}  ${:>7.2f}".format(item, qty, unit_price))

# f-string
print(f"{item:<12} {qty:>4}  ${unit_price:>7.2f}")

# All print:
# widget         42  $   4.50

Итоги

  • Используйте f-строки для нового кода Python 3.6+: они наиболее читаемы и быстры.
  • Используйте str.format(), когда нужен многократно используемый строковый шаблон или необходима поддержка Python 2.6+.
  • Используйте % только в устаревшем коде или при работе с модулем logging (который откладывает форматирование до момента фактической записи в лог).
  • Мини-язык спецификации формата (width, precision, align, fill, type) применяется одинаково как к str.format(), так и к f-строкам.

Связанные главы:

  • Python f-Strings — подробное описание выражений f-строк и возможностей Python 3.12
  • Python Strings — основы строк, индексирование и срезы
  • Modify Strings — встроенные строковые методы
  • Escape Characters — специальные символы в строках

Практика

Практика
Which of the following are valid methods for formatting strings in Python, as described in the content of the specified URL?
Which of the following are valid methods for formatting strings in Python, as described in the content of the specified URL?
Was this page helpful?