Что означает TypeError в Python
TypeError в Python — это отказ выполнить действие, потому что у значения неподходящий тип. Число, строка, список и логическое значение умеют разные вещи, и Python не угадывает, что вы имели в виду.
У каждого значения в Python есть тип: 7 — целое число int, "7" — строка str, 7.0 — дробное float. Узнать его помогает функция type(), описанная в документации Python среди встроенных. Для чисел знак «+» означает сложение, для строк — склейку. Когда слева строка, а справа число, Python не берётся решать, склеивать или складывать, и честно сообщает о несовместимых типах. В официальной документации Python[1] TypeError описан как исключение, которое возникает, когда операция или функция применяется к объекту неподходящего типа.
В отличие от синтаксической ошибки, эта проявляется во время работы: строки выше успевают выполниться. Запустите программу в редакторе над статьёй — Python выполнит первые две строки и остановится на третьей. Подсказка под выводом объяснит, что пошло не так, а исправить вы сможете сами, прочитав следующий раздел.
Строка плюс число: can only concatenate str
Сообщение can only concatenate str (not "int") to str — это самый частый TypeError у новичков: к строке пытаются приклеить число знаком «+».
ochki = 40
print("У тебя " + ochki + " очков")
Traceback (most recent call last):
File "main.py", line 2, in <module>
print("У тебя " + ochki + " очков")
~~~~~~~~~~^~~~~~~
TypeError: can only concatenate str (not "int") to str
Перевод сообщения: «склеивать можно только строку со строкой, а тут число». Исправить можно тремя способами, и все они дают одинаковый вывод:
ochki = 40
print("У тебя " + str(ochki) + " очков")
print("У тебя", ochki, "очков")
print(f"У тебя {ochki} очков")
Первый способ превращает число в строку функцией str(). Второй вообще обходится без «+»: print через запятую сам выводит значения любых типов и ставит между ними пробел. Третий — f-строка: значение подставляется в фигурные скобки; в документации Python она описана в разделе о форматировании вывода. Для вывода удобнее всего запятые или f-строки, подробнее о них — в уроке про функцию print. А вот склейку через str() стоит знать на случай, когда нужно собрать строку и сохранить её в переменную.
Число плюс строка: unsupported operand
Если число стоит слева, а строка справа, сообщение другое — unsupported operand type(s) for +: 'int' and 'str'. Суть та же: 2 несовместимых типа в одной операции.
Чаще всего эта ситуация возникает с input(). Функция ввода всегда возвращает строку, даже если пользователь набрал цифры: по документации Python она читает строку текста и отдаёт её без символа перевода строки. Поэтому 10 + input() или input() + 1 упадут. Проверьте себя:
god = input("Какой сейчас год? ")
print("Следующий:", god + 1)
Пользователь ввёл 2030, но в переменной лежит строка "2030", и прибавить к ней единицу нельзя. Решение — превратить ввод в число сразу при чтении:
god = int(input("Какой сейчас год? "))
print("Следующий:", god + 1)
Такая же ошибка типов бывает с другими операциями. Сравнение 3 < "4" даст сообщение «'<' not supported between instances of 'int' and 'str'», а sum(["1", "2"]) упадёт, потому что пытается сложить 0 со строкой. Интересное исключение — умножение: "5" * 3 работает и даёт 555, потому что строку можно повторить целое число раз. А вот "5" * 3.0 снова приведёт к ошибке: повторить строку «три целых ноль десятых раза» не получится. Как читать ввод и переводить его в числа, подробно разобрано в статье про функцию input.
Приведение типов: таблица
Приведение типов — это превращение значения одного типа в другой с помощью функций int(), float(), str(). Это главный инструмент против несовместимых типов.
| Запись | Результат | Тип результата |
int("42") | 42 | int |
float("2.5") | 2.5 | float |
str(15) | '15' | str |
int(3.9) | 3 — дробная часть отбрасывается | int |
int("3.9") | ошибка ValueError, а не TypeError | — |
"5" * 3 | '555' — повтор строки | str |
Обратите внимание на пятую строку: если тип правильный, но содержимое строки не похоже на целое число, возникает уже другая ошибка. Её разбирает статья про ValueError при вводе чисел. Функции int(), float() и str() входят в список встроенных функций из официальной документации Python, поэтому импортировать ничего не нужно. Обзор всех основных типов есть в уроке о типах данных Python.
Миф: «Python сам догадается, что "5" + 3 — это 8». Такого поведения не существует: Python специально не превращает типы молча, чтобы не скрывать ошибки. Выбор между склейкой и сложением всегда остаётся за программистом.
Вызов не функции: object is not callable
Сообщение 'int' object is not callable означает, что после значения стоят круглые скобки, как будто это функция. Число, строку или список вызвать нельзя.
Есть 2 частых сценария. Первый — пропущен знак умножения: в математике пишут 5(3 + 2), а в Python нужно 5 * (3 + 2). Без звёздочки интерпретатор видит число со скобками после него и пытается его «вызвать». Второй сценарий хитрее — переменная перекрыла встроенную функцию:
print = "Привет"
print("Мир")
После первой строки имя print указывает на строку, а не на функцию вывода, и вторая строка падает с сообщением «'str' object is not callable». То же самое случается с именами sum, max, len, input, list, str: стоит назвать так переменную, и встроенная функция пропадёт до перезапуска программы. Руководство PEP 8 описывает приём с подчёркиванием в конце имени, например class_, для совпадений с ключевыми словами[2]; со встроенными функциями проще всего выбрать другое слово: summa вместо sum.
Неверное число аргументов
Если функцию вызвать с меньшим или большим числом аргументов, чем в её определении, Python тоже выдаёт TypeError с точным указанием, чего не хватает.
def ploshad(dlina, shirina):
return dlina * shirina
print(ploshad(5))
Сообщение будет таким: ploshad() missing 1 required positional argument: 'shirina' — не хватает одного обязательного аргумента, и Python даже называет его. Обратная ситуация — лишний аргумент: ploshad(5, 3, 2) вызовет «takes 2 positional arguments but 3 were given». Исправление в обоих случаях одинаковое: посмотрите на строку def и передайте ровно столько значений, сколько там параметров. Подробно о параметрах и значениях по умолчанию — в уроке про функции в Python.
Встроенные функции тоже проверяют типы аргументов. Запись len(12345) вызовет «object of type 'int' has no len()»: длину можно узнать у строки или списка, но не у числа. Если нужно количество цифр, сначала превратите число в строку: len(str(12345)) даст 5.
Как исправить TypeError в Python по шагам
Чтобы исправить TypeError в Python, выполните 4 действия: прочитайте последнюю строку сообщения, найдите в ней названия типов, проверьте тип каждой переменной в проблемной строке и приведите их к одному.
- Названия типов. В сообщении почти всегда есть слова вроде 'int' и 'str' — это и есть конфликтующая пара.
- Проверка через print. Перед проблемной строкой временно добавьте
print(type(x))для каждой переменной. - Источник значения. Если переменная пришла из
input(), это строка, пока вы не обернули её вint(). - Приведение. Выберите нужный тип по смыслу: для арифметики — число, для склейки текста — строка.
Миф: «Если обернуть всё подряд в str(), ошибок типов не будет». Это не подтверждается практикой: ошибка исчезнет, но
str(2) + str(3)даст «23», а не 5, и программа станет считать неправильно.
Когда приведение типов не поможет
Приведение типов не поможет, если причина в другом: в имени, перекрывшем функцию, или в устройстве самой задачи. Вот 4 таких случая.
- Переменная названа как 1 из встроенных функций. Переименуйте её и перезапустите программу.
- Функции передано 2 аргумента вместо 3. Тут нужен недостающий аргумент, а не
int(). - Строку умножают на 2.5. Повторить текст можно только целое число раз.
- В строке «3,5» запятая вместо точки.
float()не примет её, и вместо 1 ошибки получится другая — ValueError.
Чего делать нельзя
Нельзя менять типы вслепую, лишь бы пропало сообщение: программа начнёт работать, но с неправильным результатом. Вот правила.
- Нельзя складывать результат input() с числом без
int()илиfloat(). - Не стоит называть переменные print, sum, max, len — встроенная функция перестанет работать.
- Не следует превращать числа в строки до вычислений — сначала посчитайте, потом выводите.
- Нельзя писать 5(3 + 2) вместо
5 * (3 + 2): знак умножения в Python обязателен. - Не стоит угадывать число аргументов — откройте строку
defи сверьтесь. - Не допускается сравнивать строку с числом через
<или>: приведите их к одному типу.
Источники
[1] The Python Tutorial (официальная документация Python 3). Python Software Foundation. — синтаксис и встроенные функции.
[2] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
[3] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования». — информатика 7–9.
Вопросы и ответы
Почему input() возвращает строку, даже если ввели цифры?
Клавиатура передаёт символы, а не числа. Python не знает заранее, что вы хотите получить, поэтому отдаёт текст, а превращение в число оставляет вам.
Почему "5" * 3 работает, а "5" + 3 — нет?
Умножение строки на целое число имеет понятный смысл — повторить её. У сложения строки с числом однозначного смысла нет, поэтому Python отказывается.
Чем TypeError в Python отличается от ValueError?
При ошибке типов не подходит сам тип, например строка вместо числа. ValueError возникает, когда тип верный, но значение плохое: int("абв") получает строку, как и положено, но превратить её в число не может.
Где про типы данных говорится в школьной программе?
Федеральная образовательная программа основного общего образования относит целые, вещественные и символьные переменные к 8 классу[3]. С этого момента и стоит следить, какого типа каждое значение в программе.
Встречается ли ошибка типов на ОГЭ?
По материалам ФИПИ задание 16 ОГЭ по информатике — программа на универсальном языке, и Python входит в список. Ввод там читается через input(), так что забытый int() сразу даст несовместимые типы.
Как быстро узнать тип переменной?
Выведите print(type(x)). Ответ вроде <class 'str'> сразу покажет, строка перед вами или число.
Что делать, если ошибка указывает внутрь чужой функции?
Смотрите на последнюю строку вашего кода в сообщении: обычно именно вы передали в функцию значение не того типа. Исправлять нужно вызов, а не саму функцию.