💻 Практические примеры

⚡ Шпаргалка по методам строк и форматированию

text = "  Python 2026  "
clean = text.strip().replace("2026", "2027")
print(clean.upper())                      # PYTHON 2027
print(clean.isalpha(), clean.find("th"))  # False 2
name, score = "Alice", 92.5
print(f"[{name:<10}{score:>8.1f}]")      # [Alice         92.5]
ГруппаМетодыЧто делает
Предикатыisalpha, isdigit, startswith, endswithпроверяют содержимое строки, возвращают True/False
Поискfind, rfind, index, rindex, countfind безопасен (-1), index кидает ValueError
Регистрupper, lower, capitalize, title, swapcase, casefoldвозвращают новую строку с изменённым регистром
Разбор/сборка/выравниваниеsplit, join, strip, center, ljust, rjust, zfillразбивают, склеивают, чистят края, выравнивают по ширине
Форматирование%-style, format(), f-stringsвставляют значения в строку; f-strings короче
Топ-3 ошибки: find() вернёт -1, а index() кинет ValueError · забыть сохранить результат метода в переменную · забыть префикс f у f-strings.

Двенадцать примеров идут от простого к сложному: сначала базовые свойства строк, затем — по группам методов лекции (предикаты, поиск, регистр, split/join, strip, выравнивание, форматирование), и в конце — сборка нескольких приёмов в одной практической задаче. Весь вывод в комментариях получен реальным запуском кода.

Пример 1. Строки неизменяемы: методы возвращают новую строку

Это базовое свойство держит на себе всю тему: любой метод строки не меняет исходный объект, а создаёт новый.

text = "  Python Summary  "
upper_text = text.upper()

print(repr(text))         # '  Python Summary  ' — исходная строка не изменилась
print(repr(upper_text))   # '  PYTHON SUMMARY  '

result = text.strip().lower().replace("python", "language")
print(repr(result))       # 'language summary'

Что происходит: text.upper() не изменяет text — он остаётся тем же объектом с теми же пробелами и регистром. Методы можно объединять в цепочку (strip().lower().replace(...)), потому что каждый возвращает новую строку, у которой снова можно вызвать метод.

Пример 2. Предикаты: классификация текста

Предикатные методы отвечают на вопрос «из чего состоит строка» и часто используются для проверки пользовательского ввода до дальнейшей обработки.

def classify_token(token):
    if token.isdigit():
        return "число"
    if token.isalpha():
        return "слово"
    if token.isspace():
        return "пробел"
    return "смешанный текст"


tokens = ["2026", "Python", "   ", "py3.14"]
for token in tokens:
    print(repr(token), "->", classify_token(token))
# '2026' -> число
# 'Python' -> слово
# '   ' -> пробел
# 'py3.14' -> смешанный текст

print("Hello".startswith("He"), "Hello".endswith("lo"))  # True True
print("Hello World".istitle(), "hello world".istitle())  # True False

Почему так: порядок проверок важен — "py3.14" не проходит ни isdigit(), ни isalpha() (в строке есть и буквы, и цифры, и точка), поэтому попадает в общий случай. Каждый предикат проверяет строку целиком, а не отдельные символы.

Пример 3. isdecimal(), isdigit(), isnumeric() — не одно и то же

Три метода отвечают на разные по строгости вопросы о «числовости» строки. Разница проявляется на символах вне обычных цифр 0–9: надстрочных цифрах, римских цифрах, дробях.

print("123".isdecimal(), "123".isdigit(), "123".isnumeric())  # True True True
print("²".isdecimal(), "²".isdigit(), "²".isnumeric())  # False True True  (надстрочная цифра ²)
print("Ⅷ".isdecimal(), "Ⅷ".isdigit(), "Ⅷ".isnumeric())  # False False True (римская цифра Ⅷ)

print("total_2026".isidentifier(), "2026_total".isidentifier())  # True False
print("Python".isascii(), "Питон".isascii())                     # True False
print("line1\nline2".isprintable())                              # False

Что происходит: isdecimal() — самый строгий (только обычные десятичные цифры), isdigit() шире (плюс надстрочные формы), isnumeric() самый широкий (плюс римские цифры и дроби). isidentifier() проверяет, годится ли строка как имя переменной — "2026_total" не годится, потому что начинается с цифры.

Пример 4. Поиск подстроки: безопасный и «падающий» варианты

find()/rfind() возвращают -1, если подстрока не найдена — с ними удобно проверять условием. index()/rindex() в этой ситуации кидают исключение.

text = "Python is awesome. Python is dynamic."
print(text.find("Python"), text.rfind("Python"))  # 0 19
print(text.find("Java"))                           # -1
print(text.count("Python"))                         # 2

try:
    text.index("Java")
except ValueError as error:
    print("ValueError:", error)  # ValueError: substring not found

Почему так: используйте find(), когда отсутствие подстроки — нормальная ситуация, которую вы проверите по -1. Используйте index(), когда отсутствие подстроки — ошибка данных, которую нужно явно поймать через try/except.

Пример 5. Изменение регистра: шесть методов и одна ловушка

Методы регистра часто путают по названию. casefold() — не то же самое, что lower(): он сильнее нормализует символы других языков для сравнения строк без учёта регистра.

text = "Hello, worlD! it's a TEST"
print(text.upper())       # HELLO, WORLD! IT'S A TEST
print(text.lower())       # hello, world! it's a test
print(text.capitalize())  # Hello, world! it's a test
print(text.title())       # Hello, World! It'S A Test
print(text.swapcase())    # hELLO, WORLd! IT'S A test

print("Straße".casefold(), "Straße".lower())  # strasse straße
⚠️ Проверить по документации: casefold() выходит за рамки исходного занятия (как и в лекции урока 20) — см. str.casefold().

Подводный камень: title() считает началом слова любой символ после не-буквы, поэтому апостроф в it's ломает результат — получается It'S, а не It's. Для реальных текстов с апострофами title() нужно применять осторожно или писать свою функцию.

Пример 6. Разделение и объединение: split(), rsplit(), splitlines(), join()

Кроме привычных split()/join(), у строк есть rsplit() (разбор справа) и splitlines() (разбор по строкам — удобно для многострочного текста без ручного поиска \n).

data = "2026-08-13T10:30:00"
print(data.split("-"))       # ['2026', '08', '13T10:30:00']
print(data.split("-", 1))    # ['2026', '08-13T10:30:00']
print(data.rsplit("-", 1))   # ['2026-08', '13T10:30:00']

log = "line one\nline two\r\nline three"
print(log.splitlines())      # ['line one', 'line two', 'line three']

fruits = "apple, banana,  cherry"
print([f.strip() for f in fruits.split(",")])  # ['apple', 'banana', 'cherry']
print(" | ".join(["a", "b", "c"]))              # a | b | c
⚠️ Проверить по документации: rsplit() и splitlines() выходят за рамки исходного занятия — см. str.rsplit() и str.splitlines().

Что происходит: параметр maxsplit ограничивает число разбиений; rsplit() считает их справа, поэтому на дате результат аккуратно отделяет время от даты одним разбиением. splitlines() понимает разные символы конца строки (\n, \r\n) — в отличие от split("\n"), который сломается на \r\n.

Пример 7. Очистка краёв: strip(), lstrip(), rstrip()

Методы удаляют пробельные символы (или указанный набор символов) только с краёв — середина строки не трогается.

raw = "   ***Python 2026***   "
print(f"[{raw.strip()}]")              # [***Python 2026***]
print(f"[{raw.strip().strip('*')}]")   # [Python 2026]
print(f"[{raw.lstrip()}]")             # [***Python 2026***   ]
print(f"[{raw.rstrip()}]")             # [   ***Python 2026***]

filename = "###important_notes###"
print(filename.strip("#"))             # important_notes

Что происходит: strip("*") удаляет любые символы * с обоих краёв, но не трогает пробелы — поэтому для raw потребовались два вызова подряд: сначала пробелы, потом звёздочки. Аргумент strip() — это набор символов, а не подстрока целиком.

Пример 8. Выравнивание и заполнение: center(), ljust(), rjust(), zfill()

Эти методы готовят текст для табличного вывода в консоли — до появления удобных f-string-спецификаторов ширины они были основным инструментом.

rows = [("Alice", 92), ("Bob", 7), ("Carol", 105)]
for row_name, score in rows:
    print(row_name.ljust(10, ".") + str(score).rjust(5))
# Alice.....   92
# Bob.......    7
# Carol.....  105

print("42".zfill(5))          # 00042
print("-42".zfill(5))         # -0042
print("hi".center(10, "*"))   # ****hi****

# то же самое через спецификаторы f-строк
label = "hi"
print(f"{label:*^10}")  # ****hi****
print(f"{label:*<10}")  # hi********
print(f"{label:*>10}")  # ********hi
⚠️ Проверить по документации: методы выравнивания выходят за рамки исходного занятия (как и в лекции урока 20/22) — см. str.ljust(), str.zfill().

Что происходит: zfill() — частный случай rjust() с заполнением нулями, который дополнительно понимает знак числа: "-42".zfill(5) даёт "-0042", а не "00-42". F-string-спецификатор {значение:символ^ширина} — прямой аналог трёх методов сразу: ^ центр, < слева, > справа.

Пример 9. removeprefix() и removesuffix() против ручной вырезки (Python 3.9+)

До Python 3.9 «отрезать префикс» делали через срез и проверку startswith(). Начиная с 3.9 для этого есть отдельные методы, которые не падают, если префикса/суффикса нет.

filename = "test_report.txt"

# современный способ
name = filename.removeprefix("test_").removesuffix(".txt")
print(name)  # report

# старый способ (Python < 3.9)
old_name = filename
if old_name.startswith("test_"):
    old_name = old_name[len("test_"):]
if old_name.endswith(".txt"):
    old_name = old_name[:-len(".txt")]
print(old_name)  # report

# безопасность: префикса нет — строка не меняется, ошибки не будет
print("report.txt".removeprefix("test_"))  # report.txt
⚠️ Проверить по документации: removeprefix()/removesuffix() появились в Python 3.9 и выходят за рамки исходного занятия — см. str.removeprefix().

Почему так: частая ошибка — резать строку срезом text[5:] «на глаз», не проверив, что префикс вообще есть. removeprefix() избавляет от этой проверки: если префикса нет, строка возвращается без изменений.

Пример 10. Три способа форматирования рядом

C-style %, format() и f-strings решают одну задачу — вставить значения в строку. Результат одинаковый, но f-strings короче и позволяют вычислять выражения прямо внутри {}.

name, age, balance = "Alice", 30, 1234.5

print("Name: %s, Age: %d, Balance: %.2f" % (name, age, balance))
print("Name: {}, Age: {}, Balance: {:.2f}".format(name, age, balance))
print(f"Name: {name}, Age: {age}, Balance: {balance:.2f}")
# Name: Alice, Age: 30, Balance: 1234.50   -- все три строки одинаковы

# format() умеет переиспользовать и именовать аргументы
print("{0} is {1} years old, {0} again".format(name, age))  # Alice is 30 years old, Alice again
print("{n} is {a} years old".format(n=name, a=age))          # Alice is 30 years old

# f-string вычисляет выражения и вызывает методы прямо внутри {}
print(f"{name.upper()} turns {age + 1} next year")  # ALICE turns 31 next year

Что происходит: в %-style порядок значений в кортеже справа должен точно совпадать со спецификаторами слева — это главный источник ошибок этого стиля. format() и f-strings терпимее: именованные и индексированные аргументы можно использовать повторно.

Пример 11. Форматирование чисел: точность, разделители, знак, проценты

Спецификаторы после : в f-string управляют шириной, точностью и видом числа — этого достаточно для большинства отчётов без сторонних библиотек.

prices = {"Book": 12.5, "Pen": 1.234, "Laptop": 1234.567}
for item, price in prices.items():
    print(f"{item:<10}{price:>10,.2f}")
# Book           12.50
# Pen             1.23
# Laptop      1,234.57

pi = 3.14159265
print(f"{pi:.2f}")      # 3.14
print(f"{pi:+.2f}")     # +3.14   -- явный знак
print(f"{1234567:,}")   # 1,234,567
print(f"{42:05d}")      # 00042
print(f"{0.256:.1%}")   # 25.6%
⚠️ Проверить по документации: знак + и спецификатор процентов % выходят за рамки таблицы форматов из конспекта урока 22 — см. Format Specification Mini-Language.

Что происходит: {price:>10,.2f} сочетает сразу три спецификатора — ширину 10, разделитель тысяч запятой и два знака после точки; порядок символов после : фиксирован (заполнение/выравнивание → знак → ширина → , → .точность → тип).

Пример 12. Собираем приёмы вместе: проверка на панграмму

Задача из практики урока (см. Задание 2) — хороший повод соединить предикаты, приведение регистра и множества в одной функции, а не разбирать методы по отдельности.

import string

def is_pangram(text):
    letters_used = {char for char in text.lower() if char.isalpha()}
    return letters_used >= set(string.ascii_lowercase)

phrase = "The quick brown fox jumps over the lazy dog"
print(is_pangram(phrase))          # True
print(is_pangram("Hello world"))   # False

# вариант без множеств, через all() -- ближе к тому, что видно в уроке
def is_pangram_v2(text):
    text_lower = text.lower()
    return all(letter in text_lower for letter in string.ascii_lowercase)

print(is_pangram_v2(phrase))  # True
⚠️ Проверить по документации: модуль string и string.ascii_lowercase не упоминались в материалах этого урока — см. string.ascii_lowercase.

Что происходит: генераторное выражение {char for char in text.lower() if char.isalpha()} строит множество уникальных букв в нижнем регистре — предикат isalpha() отбрасывает пробелы, а приведение .lower() убирает влияние регистра. Сравнение множеств >= проверяет, что все 26 букв алфавита присутствуют. Этот пример — мост к уроку 32 «Множества» и к уроку 30 «List comprehension», где такая запись разбирается подробно.

Что дальше

Проверьте себя в заданиях без подсказок, сверьтесь с решениями и просмотрите типичные ошибки. Материал напрямую опирается на урок 20 «Методы строк» и урок 22 «Строки: форматирование» — если что-то из примеров непонятно, вернитесь туда за подробным разбором.

Как запустить в VS Code

  1. Создайте файл example.py в папке урока.
  2. Скопируйте код из примера выше.
  3. Откройте терминал в VS Code (Ctrl + `).
  4. Активируйте виртуальное окружение: venv\Scripts\activate (Windows) или source venv/bin/activate (Mac/Linux).
  5. Запустите: python example.py