Справочник по Python · модуль 5 · строки
Глава 5.8
Печатность, пробелы
и состояние регистра
isprintable() и isspace() проверяют служебные свойства символов и помогают ловить то, чего не видно глазом. islower(), isupper() и istitle() отвечают на вопросы о регистре букв — и все три требуют, чтобы буквы вообще были.
- Категория
- Строковые методы
- Уровень
- Базовый → средний
- Связанные темы
- Unicode, регистр, очистка строк
- Зачем это знать
- Различать видимый текст, пробелы и регистр букв
§1Состояние, а не состав
Глава 5.7 отвечала на вопрос «из чего строка состоит»: буквы, цифры, ASCII. Здесь вопросы другие — «можно ли это показать», «есть ли тут что-то кроме пробелов», «в каком регистре буквы».
Общее правило семейства остаётся прежним: условие проверяется для каждого символа. Но пустую строку разные методы трактуют по-разному, и на этом легко ошибиться.
| Метод | Вопрос | Пустая строка |
|---|---|---|
isprintable() | всё ли можно отобразить | True |
isspace() | всё ли — пробельные символы | False |
islower() | все ли буквы строчные | False |
isupper() | все ли буквы заглавные | False |
istitle() | каждое ли слово с заглавной | False |
§2isprintable(): что видно
Метод возвращает True, если строку можно вывести на экран как есть — без управляющих символов, которые не рисуются, а отдают команды.
print("Отчёт №3".isprintable()) print("Строка 1\nСтрока 2".isprintable()) print("Имя\tБалл".isprintable())
True False False
Логика здесь такая: \n не отображается сам, а перемещает курсор на новую строку; \t сдвигает его к следующей позиции табуляции. Оба — команды, а не знаки.
§3Пустая строка и пробел
Два случая, которые почти всегда удивляют.
print("".isprintable()) print(" ".isprintable())
True True
Пустая строка проходит по той же причине, что и в isascii(): непечатных символов в ней нет, значит условие выполнено. А обычный пробел — полноценный печатный символ: он занимает место и выводится, в отличие от \n.
§4Невидимые символы
Настоящая польза isprintable() — ловить то, что глазом не увидеть. Скопированный из документа или веб-страницы текст часто содержит служебные символы Unicode.
name = "ИванПетров" print(name) print(len(name)) print(name.isprintable())
ИванПетров 11 False
На экране всё выглядит нормально, но строка не совпадёт ни с "ИванПетров", ни с "Иван Петров". Такие случаи ищут по расхождению длины и по isprintable() — сравнение строк здесь бессильно, потому что глазами разницы не видно.
Символы нулевой ширины, неразрывные пробелы и мягкие переносы попадают в данные при копировании из Word, PDF и веб-страниц. Если пользователь уверяет, что ввёл всё правильно, а проверка не проходит — len() и isprintable() первыми покажут, в чём дело.
§5isspace(): только пробельные
Метод отвечает на вопрос «в строке нет ничего, кроме пробельных символов». Строка при этом должна быть непустой.
print(" \t\n".isspace()) print(" x ".isspace()) print("".isspace())
True False False
Типичное применение — отсеять ввод, который выглядит заполненным, но состоит из одних пробелов.
§6Пробелов больше одного
«Пробельный символ» — это не только клавиша пробела. Сюда входят табуляция, перевод строки, возврат каретки и ряд символов Unicode.
nbsp = " " print(nbsp.isspace()) print(nbsp.isascii()) print(nbsp.isprintable())
True False False
Неразрывный пробел выглядит как обычный, но им не является. Он не совпадёт с " " при сравнении, и именно он чаще всего попадает в текст, скопированный с веб-страницы.
§7isspace() или strip()
Задачу «строка пустая или из одних пробелов» решают двумя способами, и они не равнозначны.
line = " \n" print(line.isspace()) print(bool(line.strip()))
True False
| Строка | isspace() | bool(strip()) |
|---|---|---|
" " | True | False |
"" | False | False |
"текст" | False | True |
Разница в средней строке: isspace() для пустой строки даёт False, и проверка «пусто ли поле» через него пропустит пустой ввод. Поэтому для валидации надёжнее if not line.strip() — она покрывает оба случая сразу. Метод strip() разбирается в главе 5.9.
§8islower() и isupper()
Оба метода смотрят только на буквы. Цифры, пробелы и знаки препинания проверке не мешают — они просто не участвуют.
print("python 3!".islower()) print("Python 3!".islower()) print("PYTHON 3!".isupper()) print("PYthon".isupper())
True False True False
§9Нужна хотя бы одна буква
Если букв в строке нет вовсе, проверять нечего — и обе проверки возвращают False.
print("42a!".islower()) print("42A!".isupper()) print("42!".islower(), "42!".isupper())
True True False False
Одной строчной буквы среди цифр и знаков достаточно для islower(). А строка "42!" не является ни строчной, ни заглавной — вопрос к ней просто неприменим.
§10islower() — не отрицание isupper()
Из предыдущего параграфа следует важное: not text.isupper() и text.islower() — разные условия.
| Строка | islower() | isupper() | Почему |
|---|---|---|---|
"python" | True | False | все буквы строчные |
"PYTHON" | False | True | все буквы заглавные |
"Python" | False | False | регистр смешанный |
"42!" | False | False | букв нет вовсе |
Две последние строки дают False обеим проверкам. Значит, из «не заглавная» не следует «строчная»: между ними ещё два состояния.
§11istitle(): регистр слов
Метод проверяет, что каждая группа букв начинается с заглавной, а продолжается строчными.
print("Python Для Всех".istitle()) print("Python для всех".istitle()) print("Иван Петров".istitle())
True False True
Проверке istitle() соответствует преобразование title(): оно приводит строку ровно к такому виду. Пара работает так же, как isupper() и upper().
§12Где istitle() расходится с ожиданием
Метод считает словом любую непрерывную последовательность букв. Любой другой символ — дефис, апостроф, цифра — начинает новое «слово».
print("План-Отчёт".istitle()) print("O'Brien".istitle()) print("IPhone".istitle())
True True False
Разберём каждую. План-Отчёт — две группы букв, обе с заглавной, проверка пройдена; а вот привычное План-отчёт её не пройдёт. В O'Brien апостроф разделил O и Brien, и обе части начинаются с заглавной. А IPhone провалился: это одна группа букв, где после заглавной I идёт ещё одна заглавная P.
istitle() проверяет механическое правило, а не правила оформления заголовков в языке. Настоящий заголовок с предлогами со строчной буквы — «Война и мир» — проверку не пройдёт. Использовать метод стоит только там, где нужно именно это механическое правило.
§13Проверка не преобразует
Методы is... ничего не меняют. Это очевидно, но ошибка встречается: строку проверяют там, где хотели преобразовать.
text = "Python" upper_text = text.upper() print(text.isupper()) print(upper_text, upper_text.isupper())
False PYTHON True
| Вопрос | Действие |
|---|---|
text.isupper() | text.upper() |
text.islower() | text.lower() |
text.istitle() | text.title() |
Методы левого столбца возвращают bool, правого — новую строку. Преобразования разбирались в главе 5.2 и разбираются в 5.10.
§14Составные условия
Ни один метод главы не годится для проверки ввода в одиночку. Обычно условия соединяют.
for name in ["Анна", " ", "", "ИванПетров"]: valid = bool(name.strip()) and name.isprintable() print(repr(name), valid)
'Анна' True ' ' False '' False 'Иван\u200bПетров' False
Первое условие отсекает пустоту и одни пробелы, второе — невидимые символы. Порядок важен для читаемости, но не для результата: and из главы 3.17 в любом случае остановится на первом ложном условии.
§15Частые ошибки
| Что написано | Что произойдёт | Как правильно |
|---|---|---|
"".isprintable() как проверка ввода | вернётся True: пустая строка печатна | отдельно проверить непустоту |
line.isspace() как «поле не заполнено» | пустая строка даст False и пройдёт проверку | if not line.strip(): |
not text.isupper() вместо islower() | смешанный регистр и строки без букв дадут True | проверять то состояние, которое нужно |
"123".isupper() | False: букв нет | помнить о требовании хотя бы одной буквы |
считать isspace() проверкой одного пробела | табуляция и перевод строки тоже пройдут | сравнивать с " ", если нужен именно пробел |
принимать istitle() за правила заголовка | "Война и мир" проверку не пройдёт | писать собственное правило оформления |
| сравнивать строки, не проверив печатность | невидимый символ сделает равные строки разными | len() и isprintable() при отладке |
ждать изменения строки после isupper() | метод только отвечает на вопрос | для преобразования вызвать upper() |
§16Проверьте себя
Почему "123".islower() возвращает False?
В строке нет ни одной буквы, регистр которой можно было бы проверить. По той же причине isupper() тоже даст False.
Считает ли isprintable() пробел печатным символом?
Да. Обычный пробел выводится и занимает место, в отличие от \n и \t.
Что вернёт "".isspace() и почему это важно?
False. Поэтому проверка «поле не заполнено» через isspace() пропустит пустой ввод — надёжнее not line.strip().
Следует ли из not text.isupper(), что строка строчная?
Нет. Есть ещё смешанный регистр и строки без букв — в обоих случаях обе проверки ложны.
Почему "IPhone".istitle() даёт False, а "O'Brien" — True?
Апостроф разделяет группы букв, и каждая начинается с заглавной. В IPhone группа одна, и внутри неё вторая заглавная буква нарушает правило.
Как найти невидимый символ в строке?
Сравнить len() с ожидаемым числом символов и проверить isprintable().
§17Шпаргалка
text.isprintable()text.isspace()not text.strip()text.islower()text.isupper()text.istitle()bool(t.strip()) and t.isprintable()Итог главы
isprintable() отвергает управляющие символы и потому находит невидимую грязь в скопированном тексте, а пустую строку и обычный пробел считает печатными. isspace(), наоборот, требует непустой строки — из-за чего для проверки «поле не заполнено» надёжнее not text.strip(). Проверки регистра смотрят только на буквы и все три дают False, если букв нет: из «не заглавная» не следует «строчная». istitle() проверяет механическое правило, а не правила оформления заголовков.