Модуль 5 · Строки

Справочник по Python · модуль 5 · строки

Глава 5.7

5.7

Проверки содержимого строк

Методы isalpha(), isascii(), isdecimal(), isdigit(), isnumeric() и isidentifier() отвечают на разные вопросы о символах строки. Выбирать нужно проверку под формат данных, а не ту, что просто вернула True.

Категория
Строковые методы
Уровень
Базовый → средний
Связанные темы
Unicode, ввод данных, идентификаторы
Зачем это знать
Проверять текст до преобразования и обработки

§1Общее правило семейства

Все методы вида is... устроены одинаково: они возвращают True, если условие выполняется для каждого символа строки, и не меняют её саму.

main.pyчетыре независимых вопроса об одной строке
text = "Python3"

print(text.isalpha())
print(text.isalnum())
print(text.isascii())
print(text)
Выводисходная строка не изменилась
False
True
True
Python3

Первая проверка провалилась из-за одной цифры: достаточно единственного неподходящего символа, чтобы ответ стал ложным. Это отличает такие методы от поиска — они говорят о строке целиком, а не о наличии чего-то в ней.

§2Пустая строка

Отдельный вопрос — что отвечать, когда символов нет вовсе. Почти все методы семейства требуют хотя бы один символ и возвращают False.

main.pyодна строка, разные ответы
empty = ""

print(empty.isalpha())
print(empty.isdecimal())
print(empty.isascii())
Выводисключение — последняя проверка
False
False
True

isascii() выбивается из общего правила: он проверяет отсутствие символов вне ASCII, а в пустой строке таких символов нет — значит, условие выполнено. Помнить об этом стоит: проверка ввода через isascii() пропустит пустую строку.

§3isalpha(): только буквы

Метод требует, чтобы каждый символ был буквой — любого алфавита, а не только латинского.

main.pyчетыре случая
print("Python".isalpha())
print("Привет".isalpha())
print("Python 3".isalpha())
print("".isalpha())
Выводпробел, цифра и пустая строка не подходят
True
True
False
False

Обратите внимание на третью строку: пробел — не буква. Поэтому проверить имя человека через isalpha() не выйдет, двойные имена и фамилии через дефис не пройдут.

§4isascii(): диапазон 0–127

Метод проверяет не тип символов, а их кодовые точки: все ли они меньше 128. Это ровно та таблица ASCII, о которой шла речь в главе 5.1.

main.pyлатиница со знаками и кириллица
print("Python 3!".isascii())
print("Питон".isascii())
Выводпробел и знаки входят в ASCII
True
False

Первая строка содержит пробел и восклицательный знак — и всё равно проходит проверку. isascii() отвечает не на вопрос «это латинские буквы?», а на вопрос «поместится ли этот текст в один байт на символ?».

§5Три числовые проверки

Дальше идут три метода, которые кажутся одинаковыми, но образуют вложенные круги: каждый следующий шире предыдущего.

Схемаот строгого к широкому
┌─ isnumeric() ─────────────────────────┐
│  ⅕  Ⅻ                                  │
│  ┌─ isdigit() ───────────────────────┐ │
│  │  ²  ³                             │ │
│  │  ┌─ isdecimal() ────────────────┐ │ │
│  │  │  0 1 2 3 4 5 6 7 8 9  ٣      │ │ │
│  │  └──────────────────────────────┘ │ │
│  └───────────────────────────────────┘ │
└────────────────────────────────────────┘
main.pyодни символы, три ответа
for sample in ["42", "²", "⅕"]:
    print(sample, sample.isdecimal(), sample.isdigit(), sample.isnumeric())
Выводкаждая проверка шире предыдущей
42 True True True
² False True True
⅕ False False True

Правило вложенности: если isdecimal() вернул True, два других тоже вернут True. Обратное неверно.

§6isdecimal()

Самая строгая проверка: символ должен быть обычной десятичной цифрой, из которой можно составить число.

main.pyзнак и точка цифрами не являются
print("2026".isdecimal())
print("-12".isdecimal())
print("3.14".isdecimal())
Выводпроверяется каждый символ по отдельности
True
False
False

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

§7isdigit()

Чуть шире: кроме обычных цифр принимает символы, которые в Unicode помечены как цифровые, — например, надстрочные индексы.

main.pyверхний индекс считается цифрой
print("123".isdigit())
print("²".isdigit())
print("12 3".isdigit())
Выводпробел по-прежнему всё ломает
True
True
False

§8isnumeric()

Самая широкая проверка: сюда попадает всё, что Unicode считает числовым, включая дроби и числа других письменностей.

main.pyиероглиф, дробь и десятичная запись
print("四".isnumeric())
print("⅕".isnumeric())
print("12.5".isnumeric())
Выводточка не числовой символ
True
True
False

Последняя строка показательна: isnumeric() — самая широкая из трёх проверок, но обычное дробное число она всё равно отвергает. Точка не входит ни в одну из них.

§9Сводная таблица

Строкаisdecimal()isdigit()isnumeric()int() сработает
"42"TrueTrueTrueда
"٣" (арабская цифра)TrueTrueTrueда, даёт 3
"²"FalseTrueTrueнет
"⅕"FalseFalseTrueнет
"Ⅻ" (римская)FalseFalseTrueнет
"-12"FalseFalseFalseда
"3.14"FalseFalseFalseнет, но float() — да

Последний столбец добавлен не случайно: он показывает, что совпадения между проверкой и возможностью преобразования нет ни в одну сторону.

§10Проверка не равна преобразованию

Из таблицы следуют два неприятных вывода, и оба — источник настоящих ошибок.

Первый. isdecimal() вернул True, а число получилось не то, что ожидали.

main.pyарабо-индийская цифра проходит проверку
value = "٣"

print(value.isdecimal())
print(int(value))
Выводэто тройка, но не та, что ввёл бы пользователь
True
3

Второй. Проверка вернула False, хотя строка — совершенно нормальное число.

main.pyотрицательное число
value = "-12"

print(value.isdecimal())
print(int(value))
Выводпроверка провалилась, преобразование прошло
False
-12
Главный вывод главы

isdecimal() — это не проверка «строку можно превратить в число». Она отвергает минусы, точки и пробелы и пропускает цифры чужих письменностей. Использовать её как условие перед int() — распространённая и незаметная ошибка.

§11Как проверять число на самом деле

Надёжный способ узнать, преобразуется ли строка в число, — попробовать её преобразовать. Полноценный разбор try и except будет в модуле 8, но выглядит это так.

main.pyпроверка через попытку
value = "-12"

try:
    number = int(value)
    print("число:", number)
except ValueError:
    print("не число")
Выводминус не помешал
число: -12

Если же требование именно «только обычные цифры от нуля до девяти», проверки складывают: isascii() отсекает чужие письменности, isdecimal() — всё, кроме цифр.

main.pyдве проверки вместе
for value in ["42", "٣", "-12", ""]:
    print(repr(value), value.isascii() and value.isdecimal())
Выводпроходит только строка из обычных цифр
'42' True
'٣' False
'-12' False
'' False

§12isidentifier(): форма имени

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

main.pyдопустимые и недопустимые формы
for name in ["total_sum", "имя2", "2name", "user-name"]:
    print(name, name.isidentifier())
Выводцифра в начале и дефис запрещены
total_sum True
имя2 True
2name False
user-name False

Кириллица в именах допустима — Python это разрешает, хотя в реальном коде так не делают. И заметьте разницу с isalnum() из главы 5.6: там подчёркивание давало False, здесь — True.

§13Ключевые слова

У проверки есть слепое пятно: она проверяет только форму записи, но не занятость имени языком.

main.pyформа верна, имя занято
import keyword

name = "class"

print(name.isidentifier())
print(keyword.iskeyword(name))
print(name.isidentifier() and not keyword.iskeyword(name))
Выводполная проверка требует двух условий
True
True
False

Модуль keyword — часть стандартной библиотеки; подключение модулей разбирается в главе 6.4. Без второй проверки программа, генерирующая имена, однажды создаст переменную class или return, и код перестанет работать.

§14Проверка под задачу

Общий подход: сначала сформулировать, какие символы допустимы, и только потом подбирать метод — иногда не один.

ТребованиеПроверка
номер заказа из обычных цифрvalue.isascii() and value.isdecimal()
любое целое число, возможно со знакомпопытка int(value)
дробное числопопытка float(value)
имя переменнойisidentifier() и не ключевое слово
текст без цифр и знаковisalpha()
текст поместится в один байт на символisascii()

§15Частые ошибки

Что написаноЧто произойдётКак правильно
if value.isdecimal(): int(value)отрицательные числа не пройдут проверкупробовать int() и ловить ValueError
считать isdecimal() гарантией обычных цифрарабо-индийские цифры тоже проходятдобавить isascii()
считать isnumeric() проверкой floatточка даёт False, а дробь ⅕ — Trueпробовать float()
"".isascii() как проверка вводавернётся True: пустая строка проходитотдельно проверить длину
"-12".isdigit()False из-за минусаметоды смотрят на символы, не на синтаксис числа
"class".isidentifier()True: форма верна, но имя занятодобавить not keyword.iskeyword(name)
"Иван Петров".isalpha()False из-за пробелапроверять слова по отдельности
считать isascii() проверкой латиницыцифры, пробелы и знаки тоже проходятсочетать с isalpha()

§16Проверьте себя

Почему "Python3".isalpha() возвращает False?

Условие должно выполняться для каждого символа, а цифра 3 буквой не является.

Какая из трёх числовых проверок самая широкая?

isnumeric(). Внутри неё isdigit(), а внутри него — isdecimal().

Почему isdecimal() — плохая проверка перед int()?

Она отвергает "-12", которое прекрасно преобразуется, и пропускает цифры чужих письменностей.

Какой метод возвращает True для пустой строки?

isascii(): в пустой строке нет символов вне ASCII, значит условие выполнено.

Достаточно ли isidentifier() для выбора имени переменной?

Нет. Ключевые слова вроде class проходят проверку формы, их отсеивают через keyword.iskeyword().

Как проверить, что строка — обычное целое число из цифр?

value.isascii() and value.isdecimal(), а если допустим знак — попыткой int(value).

§17Шпаргалка

Только буквыtext.isalpha()
Только ASCIItext.isascii()
Десятичные цифрыtext.isdecimal()
Ширеtext.isdigit()text.isnumeric()
Обычное числоtext.isascii() and text.isdecimal()
Имя Pythontext.isidentifier()
Не ключевое словоkeyword.iskeyword(name)

Итог главы

Методы is... проверяют свойство каждого символа и требуют непустой строки — кроме isascii(), который пустую строку пропускает. Три числовые проверки образуют вложенные группы от isdecimal() к isnumeric(), но ни одна из них не отвечает на вопрос «это число»: минус и точка не проходят, а чужие цифры проходят. Для преобразования надёжнее попытка int() или float(), а описание формата стоит формулировать раньше, чем подбирать метод.

Глава 5.7 · Проверки содержимого строк · Справочник по Python Автор: Макаров Максим Николаевич