Строка — неизменяемая последовательность символов: ни один метод строки не меняет её на месте, каждый возвращает новую строку. Примеры идут от этого базового факта к инструментам форматирования — сначала f-strings как основной современный способ, затем str.format() и полезные строковые методы. Материал занятия — C-style (%), format() и f-strings — подробно сопоставлен в old-vs-new.html; здесь мы сосредоточимся на актуальном подходе и разберём его глубже. Весь вывод в комментариях получен реальным запуском кода (Python 3.11.9), а не подобран по памяти.
Пример 1. Строка — неизменяемая последовательность
Методы строк (.upper(), .strip(), .replace() и другие) не меняют исходную строку — они возвращают новую. Присвоить значение элементу строки по индексу тоже нельзя. Это фундамент темы: раз строку нельзя изменить «на месте», форматирование всегда работает через создание новой строки.
name = "Alice"
upper_name = name.upper()
print(name) # Alice — исходная строка не изменилась
print(upper_name) # ALICE — метод вернул новую строку
try:
name[0] = "a"
except TypeError as error:
print("TypeError:", error)
# TypeError: 'str' object does not support item assignment
Почему так: строки в Python — immutable-объекты. Это касается и подробно разобрано в уроке 20 «Методы строк» и уроке 14 «Введение в строки»; здесь важно держать это в голове при любом форматировании — результат форматирования всегда новая строка.
Пример 2. Конкатенация + и повторение *
Самый простой способ собрать строку — сложить её части оператором + или размножить оператором *. Оба оператора тоже не меняют операнды, а создают новую строку.
first = "Python"
second = "Fundamentals"
title = first + " " + second
print(title) # Python Fundamentals
separator = "-" * 20
print(separator) # --------------------
greeting = "Hi! " * 3
print(greeting) # Hi! Hi! Hi!
Что происходит: + клеит строки друг с другом (типы должны совпадать — числа нужно оборачивать в str()), * повторяет строку заданное число раз. Для длинных шаблонов с переменными это неудобно — дальше показаны более читаемые инструменты.
Пример 3. f-strings: базовое использование
f-strings (f"...") появились в Python 3.6 и сегодня — стандартный способ форматирования. Перед переменной или выражением внутри {} ничего писать не нужно, значение подставляется автоматически.
name = "Bob"
age = 25
message = f"My name is {name} and I am {age} years old."
print(message)
# My name is Bob and I am 25 years old.
Что происходит: внутри {} Python вычисляет то, что там написано, преобразует результат в строку и подставляет на место скобок. Без префикса f фигурные скобки остались бы обычным текстом — см. типичные ошибки.
Пример 4. f-strings: выражения и вызовы методов внутри {}
Внутри {} можно писать не только имя переменной, а любое Python-выражение: арифметику, вызов метода, обращение к элементу коллекции.
word = "python"
x, y = 10, 20
print(f"The sum of {x} and {y} is {x + y}.")
# The sum of 10 and 20 is 30.
print(f"'{word}' in upper case: {word.upper()}, length: {len(word)}.")
# 'python' in upper case: PYTHON, length: 6.
Почему так: f-string — это не просто шаблон, а часть кода, которая вычисляется в момент выполнения строки. Отсюда следует важное ограничение: f-string нельзя «сохранить про запас» без уже определённых переменных — она вычисляется сразу, в отличие от "{}".format(...) из примера 6.
Пример 5. Спецификаторы формата: точность, ширина, выравнивание, нули
После двоеточия внутри {} указывается спецификатор формата — он управляет тем, как именно значение превращается в текст: сколько знаков после точки, какая ширина поля, куда прижать содержимое, чем заполнить пустоту.
pi = 3.14159
price = 1234567.89
print(f"Pi ≈ {pi:.2f}") # Pi ≈ 3.14
print(f"Price: ${price:,.2f}") # Price: $1,234,567.89
label = "Python"
print(f"[{label:<10}]") # [Python ]
print(f"[{label:>10}]") # [ Python]
print(f"[{label:^10}]") # [ Python ]
number = 42
print(f"{number:05}") # 00042
Что происходит: .2f округляет float до двух знаков (не отсекает — округляет по правилам арифметики), запятая перед .2f добавляет разделитель тысяч, </>/^ задают выравнивание при фиксированной ширине поля, а 0 перед шириной заполняет пустоту нулями вместо пробелов.
Пример 6. str.format() как альтернатива f-strings
str.format() появился раньше f-strings и решает ту же задачу через метод строки: плейсхолдеры {} заполняются позиционными или именованными аргументами. Главное отличие от f-strings: шаблон можно хранить отдельно от данных и применить позже.
name = "Carol"
age = 28
print("Name: {}, Age: {}".format(name, age))
# Name: Carol, Age: 28
print("Name: {n}, Age: {a}".format(n=name, a=age))
# Name: Carol, Age: 28
template = "Hello, {}!" # шаблон хранится отдельно от данных
print(template.format("World"))
# Hello, World!
Почему так: f-string вычисляется в момент создания и требует, чтобы переменные уже существовали в этой точке кода; template в примере — обычная строка, её можно передать в функцию или прочитать из файла, а заполнить значениями — позже. Это и есть случай, где format() предпочтительнее f-strings.
Пример 7. Именованные плейсхолдеры и .format_map()
Если данные уже лежат в словаре, .format_map() подставляет их по ключам без распаковки **. Плейсхолдеры в шаблоне совпадают с ключами словаря.
user = {"name": "Dave", "age": 41}
print("Name: {name}, Age: {age}".format_map(user))
# Name: Dave, Age: 41
.format_map() не разбирался на занятии — это дополнение курса. Сверьтесь с разделом str.format_map официальной документации.
Пример 8. Экранирование фигурных скобок {{ }}
Если внутри f-string или шаблона format() нужны буквальные фигурные скобки (например, для показа кода или JSON), их нужно удвоить: {{ и }} выводятся как одна скобка.
value = 5
print(f"{{value}} equals {value}")
# {value} equals 5
print("Use {{}} for literal braces: {}".format("like this"))
# Use {} for literal braces: like this
Что происходит: одиночная { в f-string или в шаблоне format() всегда открывает плейсхолдер, поэтому единственный способ вывести саму скобку — написать её дважды.
Пример 9. Отладочный вывод f"{x=}"
Спецификатор = (Python 3.8+) печатает и имя выражения, и его значение — удобно для быстрой отладки print-ами, без ручного набора "x =", x.
count = 7
print(f"{count=}")
# count=7
items = ["a", "b", "c"]
print(f"{len(items)=}")
# len(items)=3
= появился в Python 3.8 и не входит в материалы занятия. Сверьтесь с разделом f-strings официальной документации.
Пример 10. Полезные строковые методы для подготовки текста
Форматирование редко ограничивается одной f-string — часто строку сначала нужно очистить, разбить и снова собрать. .strip(), .split(), .join(), .upper()/.lower() и .zfill() — методы, которые постоянно встречаются рядом с форматированием.
raw = " Python Fundamentals "
clean = raw.strip()
print(f"'{clean}'")
# 'Python Fundamentals'
parts = clean.split()
print(parts)
# ['Python', 'Fundamentals']
joined = "-".join(parts)
print(joined)
# Python-Fundamentals
print(clean.upper(), clean.lower())
# PYTHON FUNDAMENTALS python fundamentals
code = "7"
print(code.zfill(4))
# 0007
Что происходит: .strip() убирает пробелы по краям, .split() без аргумента режет по любым пробельным символам, .join() — это метод строки-разделителя, а не списка ("-".join(...), не list.join("-")), .zfill(4) дополняет строку нулями слева до нужной длины — короткая альтернатива f"{code:0>4}" для строк.
Пример 11. Границы применимости и типичные ошибки
Два нюанса, о которые часто спотыкаются: повторное использование одинаковых кавычек внутри выражения f-string и ошибочное ожидание, что += меняет строку «на месте».
data = {"key": "value"}
print(f"{data['key']}")
# value — разные кавычки: строка снаружи f"...", ключ внутри '...'
source_with_same_quotes = 'f"{data["key"]}"'
try:
compile(source_with_same_quotes, "<demo>", "eval")
except SyntaxError as error:
print("SyntaxError:", error)
# SyntaxError: f-string: unmatched '[' (<demo>, line 1)
text = "abc"
before_id = id(text)
text += "d"
print(text, id(text) == before_id)
# abcd False — новая строка в другом месте памяти
Почему так: до Python 3.12 внутри выражения f-string нельзя было повторно использовать тот же тип кавычек, которым открыта сама f-string — компилятор обрывает разбор на первой одинаковой кавычке. Решение — снаружи "...", внутри выражения '...' (или наоборот), как в первой строке примера. Второй момент: text += "d" не дописывает символ в существующую строку, а создаёт новую и присваивает её той же переменной — id() меняется, что и подтверждает вывод.
Что делать дальше
Сопоставьте C-style, format() и f-strings подробнее в old-vs-new.html, затем переходите к заданиям. Файлы репозитория содержат те же таблицы спецификаторов в исходном виде. Если что-то не запустилось — загляните в типичные ошибки.
Как запустить в VS Code
- Создайте файл
example.pyв папке урока. - Скопируйте код из примера выше.
- Откройте терминал в VS Code (Ctrl + `).
- Активируйте виртуальное окружение:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python example.py