Ошибка TypeError: строка плюс число, лишний аргумент, вызов не функции

Ошибки Pythonобновлено 07.10.20269 мин чтенияесть тренажёр

TypeError в Python — это ошибка типов: операцию пытаются выполнить над значением, которое для неё не подходит. Классический пример — сложить строку с числом через «+». Ещё сюда относятся вызов того, что не является функцией, и неверное число аргументов. Лечится ошибка приведением типов через int(), str() или float().

Загружаем…

Что означает 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")42int
float("2.5")2.5float
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 действия: прочитайте последнюю строку сообщения, найдите в ней названия типов, проверьте тип каждой переменной в проблемной строке и приведите их к одному.

  1. Названия типов. В сообщении почти всегда есть слова вроде 'int' и 'str' — это и есть конфликтующая пара.
  2. Проверка через print. Перед проблемной строкой временно добавьте print(type(x)) для каждой переменной.
  3. Источник значения. Если переменная пришла из input(), это строка, пока вы не обернули её в int().
  4. Приведение. Выберите нужный тип по смыслу: для арифметики — число, для склейки текста — строка.

Миф: «Если обернуть всё подряд в 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'> сразу покажет, строка перед вами или число.

Что делать, если ошибка указывает внутрь чужой функции?

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