Двенадцать примеров идут от простого к сложному: сначала базовые свойства строк, затем — по группам методов лекции (предикаты, поиск, регистр, 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
Что происходит: 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
- Создайте файл
example.pyв папке урока. - Скопируйте код из примера выше.
- Откройте терминал в VS Code (Ctrl + `).
- Активируйте виртуальное окружение:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python example.py