Два самых частых исключения в Python различаются одним вопросом, и различие не косметическое: оно сразу говорит, что чинить.
TypeError — объект не того типа. Операция к такому типу неприменима в принципе, и никакое значение этого типа не подойдёт.
ValueError — тип верный, а значение не годится. Операция применима, но конкретно с этими данными выполниться не может.
Тип не подходит или значение не годится
TypeError обычно значит, что данные пришли не оттуда, а ValueError — что источник верный, но содержимое надо проверять.Одна функция, три аргумента, два разных исключения
for value in ["10", "десять", None]:
try:
print(f"int({value!r}) = {int(value)}")
except (TypeError, ValueError) as exc:
print(f"int({value!r}) → {type(exc).__name__}: {exc}")
int('10') = 10
int('десять') → ValueError: invalid literal for int() with base 10: 'десять'
int(None) → TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
"десять" — строка, то есть тип для int() подходящий; не годится содержимое, отсюда ValueError. None вообще не тот тип — TypeError. Строка "10" проходит обе проверки.
Это не частный случай, а общее правило. Оно работает предсказательно: посмотри на аргумент, реши, где он не так, — и уже знаешь, какое исключение увидишь.
Правило предсказывает: распаковка
Одна и та же операция, три разных неудачи:
def three_from_two():
a, b, c = [1, 2]
def two_from_three():
a, b = [1, 2, 3]
def two_from_int():
a, b = 5
cases = [("a, b, c = [1, 2]", three_from_two),
("a, b = [1, 2, 3]", two_from_three),
("a, b = 5", two_from_int)]
for label, fn in cases:
try:
fn()
except (TypeError, ValueError) as exc:
print(f"{label:18} → {type(exc).__name__}: {exc}")
a, b, c = [1, 2] → ValueError: not enough values to unpack (expected 3, got 2)
a, b = [1, 2, 3] → ValueError: too many values to unpack (expected 2, got 3)
a, b = 5 → TypeError: cannot unpack non-iterable int object
Список из двух элементов там, где ждут три, — правильный тип с негодной длиной, значит ValueError. Число вместо последовательности — не тот тип, значит TypeError. Правило сработало оба раза, ещё до запуска.
Объект не вызывается
Единственное частое сообщение, которое сбивает с толку формулировкой:
prices = {"мышь": 100}
try:
prices("мышь")
except TypeError as exc:
print(f"TypeError: {exc}")
total = 5
try:
total(1)
except TypeError as exc:
print(f"TypeError: {exc}")
TypeError: 'dict' object is not callable
TypeError: 'int' object is not callable
«Not callable» значит «ты пытаешься вызвать объект, который не поддерживает вызов». Вызываемыми бывают не только функции, но и классы, и экземпляры с __call__. Частые причины ошибки: перепутаны круглые скобки с квадратными (prices("мышь") вместо prices["мышь"]) или имя функции затёрто значением — где-то выше по коду total = 5 заменил функцию total.
Таблица частых сообщений
Каждое разобрано подробно в своей статье — тип ошибки говорит, что чинить, а ссылка ведёт туда, где показано как.
| Сообщение | Что произошло | Подробный разбор |
|---|---|---|
invalid literal for int() with base 10 | строка не похожа на число | преобразование типов |
can only concatenate str (not "int") to str | сложение строки с числом | преобразование типов |
unsupported operand type(s) for + | операция неприменима к этой паре типов | дата и время |
'NoneType' object is not subscriptable | обращение по ключу к None | словари |
'int' object is not iterable | цикл по тому, что не последовательность | циклы |
takes N positional arguments but M were given | неверное число аргументов | args и kwargs |
unhashable type: 'list' | список как ключ словаря | изменяемые и неизменяемые |
substring not found | index() не нашёл подстроку | методы строк |
list.remove(x): x not in list | удаление отсутствующего элемента | методы списков |
'NoneType' object has no attribute | вызов метода у None | AttributeError |
Как ловить
Ловить эти два исключения вместе имеет смысл там, где данные приходят извне и любая беда с ними обрабатывается одинаково:
def parse_age(raw):
try:
return int(raw)
except (TypeError, ValueError):
return None
print(parse_age("42"), parse_age("сорок два"), parse_age(None))
42 None None
Порознь — когда реакция разная: на ValueError осмысленно попросить пользователя ввести значение заново, а TypeError обычно означает изъян в коде, и глушить его молча значит спрятать баг. Механика самого try/except, включая else, finally и свои исключения, разобрана в отдельной статье.
Частые вопросы
Чем TypeError отличается от ValueError
TypeError — объект не того типа, операция к нему неприменима вообще. ValueError — тип подходит, но конкретное значение обработать нельзя. int(None) даёт первое, int("десять") — второе.
Что значит object is not callable
Что после объекта стоят круглые скобки, но он не поддерживает вызов. Чаще всего это перепутанные скобки — prices("ключ") вместо prices["ключ"] — или переменная, затёршая функцию с тем же именем.
Почему распаковка даёт то ValueError, то TypeError
Потому что причины разные. Неверное количество элементов — правильный тип с негодным значением, отсюда ValueError. Объект, по которому нельзя пройти вовсе, — неподходящий тип, отсюда TypeError.
Стоит ли ловить TypeError
Обычно нет. ValueError приходит от чужих данных, и его обрабатывают. TypeError почти всегда означает ошибку в собственном коде, и пусть он падает громко — так его чинят, а не прячут.
Как узнать, где именно упало
Смотри последнюю строку трассировки — там тип и сообщение, а строкой выше файл и номер строки. Если кадров много, нужен первый снизу, который принадлежит твоему коду, а не библиотеке.
Где потренироваться
Блоки на этой странице запускаются здесь же — подставь свои значения в int() и посмотри, какое из двух исключений прилетит; правило проверяется за минуту. На живых задачах разбор пользовательского ввода встречается в проверке пароля.