Django-Admin.ru

TypeError в Python: частые причины и исправление

Что значит TypeError в Python: str и int, NoneType, object is not callable, лишние аргументы, unhashable type, string indices — причины и исправления.

Редакция Django-Admin.ru
· 20 мин чтения

Содержание · 14 разделов
  1. Быстрый поиск по тексту ошибки
  2. Строка и число: can only concatenate str и unsupported operand type(s)
  3. TypeError: can only concatenate str (not “int”) to str
  4. TypeError: unsupported operand type(s) for -: ‘int’ and ‘str’
  5. Сравнение строки с числом: '<' not supported between instances
  6. TypeError: can’t multiply sequence by non-int of type ‘float’
  7. Значение оказалось None: ‘NoneType’ object is not subscriptable, iterable, callable
  8. Метод изменяет объект и возвращает None
  9. Функция не дошла до return
  10. Варианты сообщения
  11. Аргументы функций: takes N positional arguments, missing required argument
  12. takes 1 positional argument but 2 were given
  13. missing 1 required positional argument
  14. got an unexpected keyword argument и got multiple values for argument
  15. Объект не вызывается: ‘str’ object is not callable
  16. Переменная затёрла встроенную функцию
  17. Атрибут и метод с одним именем
  18. Пропущен знак умножения
  19. ‘module’ object is not callable
  20. Индексы: string indices must be integers и list indices must be integers
  21. TypeError: string indices must be integers, not ‘str’
  22. list indices must be integers or slices, not float / not str
  23. ‘int’ object is not subscriptable
  24. unhashable type: ‘list’ и ‘dict’
  25. Неизменяемые объекты: does not support item assignment
  26. Число вместо коллекции: ‘int’ object is not iterable
  27. Другие частые сообщения TypeError
  28. Как найти, откуда взялся неверный тип
  29. Перехват и выбрасывание TypeError
  30. Частые вопросы
  31. Чем TypeError отличается от ValueError?
  32. Почему у меня сообщение об ошибке другое, чем в примере из интернета?
  33. Почему Python не преобразует строку в число автоматически?
  34. Как проверить тип переменной в Python?
  35. Ошибка ‘str’ object is not callable не исчезает после исправления кода. Почему?
  36. TypeError возникает внутри Django или другой библиотеки — где искать ошибку?
  37. Итог

TypeError в Python возникает, когда операция или функция получает объект неподходящего типа: строку вместо числа, None вместо списка, число вместо функции, лишний аргумент при вызове. Python не преобразует типы сам, поэтому "Возраст: " + 25 завершается ошибкой.

Traceback (most recent call last):
  File "C:\projects\app\main.py", line 2, in <module>
    print("Возраст: " + age)
          ~~~~~~~~~~~~^~~~~
TypeError: can only concatenate str (not "int") to str

Исправление всегда начинается с последней строки traceback: в ней названы типы, которые не сочетаются. Дальше нужно найти, откуда пришло значение не того типа, и либо преобразовать его (str(), int(), tuple()), либо исправить вызов. Ниже — самые частые сообщения TypeError с реальным выводом Python 3.12, причиной и исправлением.

Быстрый поиск по тексту ошибки

СообщениеЧто случилосьКак исправить
can only concatenate str (not "int") to strСтроку склеивают с числом через +f-строка или str(число)
unsupported operand type(s) for -: 'int' and 'str'Арифметика со строкой, часто — результат input()int(input()), float()
'<' not supported between instances of 'str' and 'int'Сравнение или сортировка строк вперемешку с числамиПривести к одному типу, key=int
'NoneType' object is not subscriptableФункция или метод вернули NoneДобавить return, проверить is None
'NoneType' object is not iterableЦикл по результату, который оказался NoneТо же
X() takes 1 positional argument but 2 were givenЛишний аргумент; у метода нет selfДобавить self, проверить вызов
X() missing 1 required positional argument: 'b'Не передан обязательный аргументПередать аргумент или задать значение по умолчанию
'str' object is not callableПеременная затёрла функцию str или методПереименовать переменную
'module' object is not callableВызван модуль вместо класса из негоfrom datetime import datetime
string indices must be integers, not 'str'Строку индексируют как словарьjson.loads(), .items()
list indices must be integers or slices, not floatИндекс получен делением /Целочисленное деление //
unhashable type: 'list'Список как ключ словаря или элемент множестваtuple(список)
'str' object does not support item assignmentПопытка изменить символ строкиСобрать новую строку
'int' object is not iterableЦикл по числу: for i in len(xs)range(len(xs)) или enumerate()
Object of type date is not JSON serializablejson.dumps() не знает типdefault=str или .isoformat()

TypeError относится к исключениям, которые возникают во время выполнения: программа запускается и падает на конкретной строке. Как читать traceback целиком и находить строку из своего кода, разобрано в руководстве как читать traceback и исправлять ошибки в Python.

Строка и число: can only concatenate str и unsupported operand type(s)

Самая частая группа ошибок у начинающих. Python строго типизирован: + складывает числа или склеивает строки, но не смешивает их.

TypeError: can only concatenate str (not “int”) to str

Строку пытаются склеить с числом:

age = 25
print("Возраст: " + age)
# → TypeError: can only concatenate str (not "int") to str

Три способа исправить:

print("Возраст: " + str(age))  # явное преобразование
print(f"Возраст: {age}")       # f-строка — самый читаемый вариант
print("Возраст:", age)         # print() сам разделит пробелом
Возраст: 25
Возраст: 25
Возраст: 25

Вместо "int" в сообщении может стоять другой тип: (not "float"), (not "list") или (not "NoneType") — последнее значит, что переменная, которую вы склеиваете, равна None. Форматирование чисел внутри строк подробно разобрано в статье про f-строки в Python.

Похожее сообщение для списков — can only concatenate list (not "int") to list — появляется при xs + 3. Чтобы добавить элемент, используйте xs.append(3), а чтобы склеить списки — xs + [3].

TypeError: unsupported operand type(s) for -: ‘int’ and ‘str’

Классический случай: функция input() всегда возвращает строку, даже если пользователь ввёл цифры.

count = input("Сколько билетов? ")
print("Осталось:", 100 - count)
Сколько билетов? 3
Traceback (most recent call last):
  File "C:\projects\app\tickets.py", line 2, in <module>
    print("Осталось:", 100 - count)
                       ~~~~^~~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'str'

В сообщении указан оператор (-) и типы левого и правого операнда в порядке записи. Исправление — преобразовать ввод в число сразу при чтении:

count = int(input("Сколько билетов? "))

Если пользователь введёт «три», int() выбросит уже другое исключение — ValueError: invalid literal for int(). Как обрабатывать некорректный ввод, разобрано в статье про ValueError в Python.

Другие варианты того же сообщения:

  • unsupported operand type(s) for +: 'int' and 'str' — например, sum(["1", "2"]): функция sum() начинает с 0 и прибавляет строки. Для чисел используйте sum(map(int, xs)), для склейки строк — "".join(xs).
  • unsupported operand type(s) for +: 'NoneType' and 'int' — одна из переменных равна None; см. раздел про NoneType ниже.

Сравнение строки с числом: '<' not supported between instances

Сравнение "10" < 5 или сортировка списка, где есть и строки, и числа:

sorted([3, "1", 2])
# → TypeError: '<' not supported between instances of 'str' and 'int'

Приведите данные к одному типу ещё при загрузке. Если нужно отсортировать как есть, задайте ключ: sorted([3, "1", 2], key=int) вернёт ['1', 2, 3].

TypeError: can’t multiply sequence by non-int of type ‘float’

Строку или список можно умножить только на целое число: "ab" * 2 даёт "abab", а "ab" * 2.5 вызывает эту ошибку. Если же вы хотели умножить число, значит, в переменной строка — снова результат input() или чтения файла. Решение: float(value) * 2.5.

Значение оказалось None: ‘NoneType’ object is not subscriptable, iterable, callable

NoneType — тип значения None. Сообщения с ним означают, что вместо ожидаемого списка, словаря или функции в переменной лежит None. Ошибка проявляется в одном месте, а причина обычно строкой-двумя выше.

Метод изменяет объект и возвращает None

scores = [72, 95, 88]
top = scores.sort(reverse=True)
print(top[0])
Traceback (most recent call last):
  File "C:\projects\app\scores.py", line 3, in <module>
    print(top[0])
          ~~~^^^
TypeError: 'NoneType' object is not subscriptable

list.sort(), list.append(), list.reverse(), dict.update(), random.shuffle() изменяют объект на месте и возвращают None. Не присваивайте их результат:

scores.sort(reverse=True)
print(scores[0])                              # → 95
print(sorted([72, 95, 88], reverse=True)[0])  # sorted() возвращает новый список → 95

Функция не дошла до return

Функция без return или с return только в одной ветке возвращает None:

users = [{"name": "Анна", "email": "anna@example.com"}]


def find_user(name):
    for user in users:
        if user["name"] == name:
            return user


print(find_user("Олег")["email"])
# → TypeError: 'NoneType' object is not subscriptable

Проверяйте результат перед использованием:

user = find_user("Олег")
if user is None:
    print("Пользователь не найден")
else:
    print(user["email"])

Так же ведут себя dict.get() без значения по умолчанию, re.match() и re.search() без совпадения, os.getenv() для незаданной переменной окружения. Во всех случаях результат может быть None, и его нужно проверить.

Варианты сообщения

СообщениеЧто сделали с None
'NoneType' object is not subscriptableОбратились по индексу или ключу: x[0]
'NoneType' object is not iterableПеребрали в цикле for или передали в list()
'NoneType' object is not callableВызвали как функцию: x()
cannot unpack non-iterable NoneType objectРаспаковали: a, b = x
unsupported operand type(s) for +: 'NoneType' and 'int'Сложили с числом
expected str, bytes or os.PathLike object, not NoneTypeПередали в open() как путь к файлу

Если вместо TypeError вы видите AttributeError: 'NoneType' object has no attribute, причина та же — у None вызвали метод. Этот случай разобран в статье про AttributeError в Python.

Аргументы функций: takes N positional arguments, missing required argument

Эти сообщения говорят, что число или имена аргументов при вызове не совпадают с определением функции. Для методов в сообщении указано и имя класса — Cat.say(), так сразу видно, о каком методе речь.

takes 1 positional argument but 2 were given

Для обычной функции это значит, что передан лишний аргумент. Но чаще всего сообщение появляется у метода класса без параметра self:

class Cat:
    def say(text):
        print(text)


cat = Cat()
cat.say("мяу")
Traceback (most recent call last):
  File "C:\projects\app\cat.py", line 7, in <module>
    cat.say("мяу")
TypeError: Cat.say() takes 1 positional argument but 2 were given

Вы передали один аргумент, а Python насчитал два: при вызове cat.say("мяу") объект cat автоматически подставляется первым аргументом. Добавьте self:

class Cat:
    def say(self, text):
        print(text)

Если метод не использует объект, объявите его через декоратор @staticmethod. Параметр self — ссылка на объект, у которого вызван метод; без него метод не получит доступ к атрибутам объекта.

missing 1 required positional argument

Обратная ситуация — аргумент не передан:

def add(a, b):
    return a + b


add(1)
# → TypeError: add() missing 1 required positional argument: 'b'

Передайте недостающий аргумент или задайте значение по умолчанию: def add(a, b=0). Особые случаи:

  • missing 1 required positional argument: 'self' — метод вызвали у класса, а не у объекта: Cat.say("мяу") вместо Cat().say("мяу"). Проверьте, что после имени класса стоят скобки.
  • User.__init__() missing 1 required positional argument: 'name' — объект создают без аргументов, которые требует __init__: User() вместо User("Анна").
  • User() takes no arguments — в имени конструктора опечатка (__int__ или _init_), и Python его не видит. Должно быть __init__ с двумя подчёркиваниями с каждой стороны.

got an unexpected keyword argument и got multiple values for argument

def greet(name, greeting="Привет"):
    return f"{greeting}, {name}!"


greet(nam="Анна")
# → TypeError: greet() got an unexpected keyword argument 'nam'
greet("Анна", name="Борис")
# → TypeError: greet() got multiple values for argument 'name'

Первое сообщение — опечатка в имени аргумента или параметр, которого у функции нет (часто после обновления библиотеки, где параметр переименовали). Начиная с Python 3.13 сообщение подсказывает правильное имя: Did you mean 'name'?. Второе — один параметр передан и по позиции, и по имени.

Чтобы посмотреть, какие параметры принимает функция, вызовите help(greet) или inspect.signature(greet):

import inspect

print(inspect.signature(greet))  # → (name, greeting='Привет')

Сообщение list.append() takes exactly one argument (2 given) из той же группы: append() добавляет один элемент, для нескольких используйте xs.extend([1, 2]).

Объект не вызывается: ‘str’ object is not callable

callable — объект, который можно вызвать круглыми скобками: функция, класс, метод. Ошибка 'X' object is not callable значит, что скобки поставлены после значения, которое функцией не является.

Переменная затёрла встроенную функцию

str = "Привет"
age = 30
print(str(age))
# → TypeError: 'str' object is not callable

После str = "Привет" имя str указывает на строку, и встроенная функция недоступна. То же бывает с list, dict, sum, max, input, type, id: сообщение будет 'list' object is not callable, 'int' object is not callable и т. д. Переименуйте переменную (text, items, total). В Jupyter Notebook или интерактивной консоли значение останется в памяти и после исправления кода — выполните del str или перезапустите ядро.

Атрибут и метод с одним именем

class User:
    def __init__(self, name):
        self.name = name

    def name(self):
        return self.name


user = User("Анна")
print(user.name())
# → TypeError: 'str' object is not callable

Атрибут self.name перекрыл метод name(). Дайте методу другое имя, например get_name(), или обращайтесь к атрибуту без скобок: user.name.

Пропущен знак умножения

x = 2
y = 2(x + 1)
C:\projects\app\calc.py:2: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
  y = 2(x + 1)
Traceback (most recent call last):
  File "C:\projects\app\calc.py", line 2, in <module>
    y = 2(x + 1)
        ^^^^^^^^
TypeError: 'int' object is not callable

В математике 2(x + 1) — умножение, в Python — вызов числа как функции. Напишите 2 * (x + 1).

‘module’ object is not callable

import datetime
datetime()
# → TypeError: 'module' object is not callable. Did you mean: 'datetime.datetime(...)'?

Имя модуля совпадает с именем класса внутри него. Импортируйте класс (from datetime import datetime) или обращайтесь по полному пути: datetime.datetime.now(). Та же ловушка есть у модулей time, pprint и glob: внутри них функции с тем же именем, поэтому вызывают time.time() или импортируют from pprint import pprint.

Индексы: string indices must be integers и list indices must be integers

TypeError: string indices must be integers, not ‘str’

Строку индексируют ключом, как словарь. Чаще всего это JSON, который получили строкой и не разобрали:

response = '{"name": "Анна", "age": 30}'
print(response["name"])
Traceback (most recent call last):
  File "C:\projects\app\api.py", line 2, in <module>
    print(response["name"])
          ~~~~~~~~^^^^^^^^
TypeError: string indices must be integers, not 'str'

Преобразуйте строку в словарь через json.loads(). Для библиотеки requests вместо response.text используйте response.json():

import json

data = json.loads(response)
print(data["name"])  # → Анна

Второй частый источник — цикл по словарю. for user in users перебирает ключи, то есть строки, и user["age"] падает с той же ошибкой. Перебирайте пары через .items():

users = {"anna": 30, "boris": 25}
for name, age in users.items():
    print(name, age)

Подробнее о разборе JSON — в статье JSON в Python.

list indices must be integers or slices, not float / not str

Индекс списка должен быть целым числом. Деление / в Python 3 всегда возвращает float, даже если делится нацело:

xs = [10, 20, 30]
xs[len(xs) / 2]
# → TypeError: list indices must be integers or slices, not float
xs[len(xs) // 2]  # целочисленное деление → 20

Вариант not str значит, что индекс пришёл строкой — из input(), аргумента командной строки или файла. Преобразуйте его: xs[int(index)].

По той же причине range(10 / 2) выдаёт TypeError: 'float' object cannot be interpreted as an integer — используйте range(10 // 2) или range(int(n)).

‘int’ object is not subscriptable

Квадратные скобки после числа: n = 2026; n[0]. Если нужна первая цифра, преобразуйте число в строку: str(n)[0] вернёт '2'. Если ожидался список, проверьте, где переменной присвоили число.

unhashable type: ‘list’ и ‘dict’

Ключи словаря и элементы множества должны быть хешируемыми — неизменяемыми объектами: числами, строками, кортежами. Список, словарь и множество изменяемы, поэтому их нельзя положить в set или использовать как ключ.

points = [[0, 0], [1, 2], [0, 0]]
unique = set(points)
Traceback (most recent call last):
  File "C:\projects\app\points.py", line 2, in <module>
    unique = set(points)
             ^^^^^^^^^^^
TypeError: unhashable type: 'list'

Преобразуйте вложенные списки в кортежи:

unique = set(map(tuple, points))
print(unique)  # → {(1, 2), (0, 0)}

Для ключа словаря тоже используйте кортеж: d[(1, 2)] = "x". Если ключом должен быть словарь, его можно заменить frozenset(d.items()) или строкой json.dumps(d, sort_keys=True).

В Python 3.14 сообщение стало подробнее и называет, куда пытались положить объект: cannot use 'list' as a set element (unhashable type: 'list') или cannot use 'list' as a dict key (unhashable type: 'list').

Неизменяемые объекты: does not support item assignment

s = "cat"
s[0] = "b"
# → TypeError: 'str' object does not support item assignment

Строки и кортежи неизменяемы: после создания их символы и элементы не меняются. Создайте новый объект:

s = "b" + s[1:]               # → bat
s = "cat".replace("c", "b")  # → bat

Для кортежа сообщение то же — 'tuple' object does not support item assignment. Если данные нужно менять, храните их в списке: list(t).

Число вместо коллекции: ‘int’ object is not iterable

xs = [10, 20, 30]
for i in len(xs):
    print(i)
# → TypeError: 'int' object is not iterable

len() возвращает число, а for перебирает только итерируемые объекты: списки, строки, словари, range. Нужны индексы — используйте range(len(xs)), нужны и индексы, и значения — enumerate(xs):

for i, x in enumerate(xs):
    print(i, x)
0 10
1 20
2 30

Родственные сообщения:

  • cannot unpack non-iterable int object — распаковка a, b = 5: справа должно быть два значения.
  • object of type 'int' has no len() — len() вызвали у числа. У генератора длины тоже нет: object of type 'generator' has no len() — преобразуйте его в список или считайте элементы в цикле.
  • 'int' object is not iterable из dict.update(5) или list(5) — функция ждёт коллекцию.

Другие частые сообщения TypeError

СообщениеПричинаИсправление
Object of type date is not JSON serializablejson.dumps() не умеет сохранять date, datetime, set, Decimaljson.dumps(data, default=str) или .isoformat()
sequence item 0: expected str instance, int foundstr.join() получил список чисел", ".join(map(str, xs))
a bytes-like object is required, not 'str'Строка передана туда, где нужны байты: файл в режиме "wb", сокетtext.encode() или открыть файл в режиме "w"
int() argument must be a string, a bytes-like object or a real number, not 'NoneType'В int() попал NoneПроверить источник значения
unsupported format string passed to NoneType.__format__f-строка с форматом {x:.2f}, где x равен NoneПроверить x is None перед форматированием
'coroutine' object is not subscriptableАсинхронную функцию вызвали без awaitdata = await get_data()
Can't instantiate abstract class Base without an implementation for abstract method 'run'Создан объект абстрактного классаРеализовать метод в наследнике и создавать наследника
isinstance() arg 2 must be a type, a tuple of types, or a unionТип передан строкой: isinstance(x, "int")isinstance(x, int)

Об ошибках с await подробнее — в статье про async/await в Python.

Как найти, откуда взялся неверный тип

Traceback показывает строку, где типы столкнулись, но не место, где переменная получила неправильное значение. Найти его помогают три приёма.

Выведите тип и значение прямо перед строкой с ошибкой:

value = "5"
print(type(value), repr(value))
# → <class 'str'> '5'

repr() показывает кавычки у строк, поэтому '5' и 5 не перепутать. Затем поднимайтесь по коду вверх до места, где переменной присвоили значение: вызов input(), чтение файла или JSON, ответ функции без return.

Остановите программу отладчиком — вставьте breakpoint() перед проблемной строкой и проверьте переменные командой p имя. Основные команды pdb: n — следующая строка, c — продолжить, q — выйти.

Проверьте типы до запуска. Аннотации типов и статический анализатор mypy находят большинство ошибок из этой статьи без запуска программы:

def total_price(price: int, count: int) -> int:
    return price * count


count = input("Сколько билетов? ")
print("Итого: " + total_price(500, count))
python -m pip install mypy
python -m mypy typed.py
typed.py:6: error: Unsupported operand types for + ("str" and "int")  [operator]
typed.py:6: error: Argument 2 to "total_price" has incompatible type "str"; expected "int"  [arg-type]
Found 2 errors in 1 file (checked 1 source file)

PyCharm подсвечивает такие места прямо в редакторе, VS Code — после включения проверки типов в расширении Pylance (настройка python.analysis.typeCheckingMode). Как писать аннотации, разобрано в статье аннотации типов в Python.

Перехват и выбрасывание TypeError

TypeError почти всегда означает ошибку в коде, поэтому её исправляют в самом коде. try/except TypeError уместен, когда в функцию могут прийти данные разных типов и для неподходящих есть разумное поведение:

def to_number(value):
    try:
        return float(value)
    except (TypeError, ValueError):
        return None


print(to_number("3.5"), to_number(None), to_number("abc"))
# → 3.5 None None

Здесь float(None) вызывает TypeError, а float("abc") — ValueError, поэтому перехватываются оба. Как правильно строить блоки try/except/else/finally, разобрано в статье try/except в Python.

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

def average(numbers):
    if not isinstance(numbers, (list, tuple)):
        raise TypeError(
            f"numbers должен быть списком или кортежем, получен {type(numbers).__name__}"
        )
    return sum(numbers) / len(numbers)


average("45")
Traceback (most recent call last):
  File "C:\projects\app\stats.py", line 10, in <module>
    average("45")
  File "C:\projects\app\stats.py", line 3, in average
    raise TypeError(
TypeError: numbers должен быть списком или кортежем, получен str

Для проверки используйте isinstance(), а не сравнение type(x) == list: isinstance() учитывает наследование и принимает кортеж из нескольких типов.

Частые вопросы

Чем TypeError отличается от ValueError?

TypeError — у объекта неподходящий тип: в int() передали None или список. ValueError — тип подходит, но значение нет: int("abc") получает строку, которую нельзя превратить в число. Поэтому при разборе пользовательского ввода обычно перехватывают оба исключения.

Почему у меня сообщение об ошибке другое, чем в примере из интернета?

Тексты сообщений меняются между версиями Python. В старых версиях Python 3 сложение строки и числа выдавало must be str, not int или Can't convert 'int' object to str implicitly. Python 3.13 добавил подсказку Did you mean для опечаток в именованных аргументах, Python 3.14 — уточнение, куда пытались положить объект, в unhashable type. Суть ошибок и способы исправления от этого не меняются.

Почему Python не преобразует строку в число автоматически?

Python не угадывает намерение программиста: "5" + 3 может означать и "53", и 8. Поэтому смешивать строки и числа в арифметике нельзя, а преобразование делают явно — int(), float(), str() или f-строкой. Исключение — числовые типы между собой: int, float и bool складываются без преобразований.

Как проверить тип переменной в Python?

type(x) возвращает точный тип, isinstance(x, int) проверяет, относится ли объект к типу или его наследнику. Для условий в коде используйте isinstance(), для быстрой отладки — print(type(x), repr(x)).

Ошибка ‘str’ object is not callable не исчезает после исправления кода. Почему?

Скорее всего, вы работаете в Jupyter Notebook, IPython или интерактивной консоли: переменная str (или list, sum) уже создана в памяти и продолжает перекрывать встроенную функцию. Выполните del str или перезапустите ядро, а затем запустите ячейки заново.

TypeError возникает внутри Django или другой библиотеки — где искать ошибку?

Почти всегда в вашем коде, который передал библиотеке значение не того типа. Найдите в traceback последний снизу кадр из файлов своего проекта и проверьте аргументы, которые там передаются: None вместо объекта, строку вместо числа, лишний позиционный аргумент.

Итог

TypeError сообщает, что операция получила объект неподходящего типа, и в последней строке traceback всегда называет эти типы. Большинство случаев сводятся к нескольким причинам: строка вместо числа (часто из input()), None вместо значения, лишний или пропущенный аргумент и self в методах, переменная с именем встроенной функции, изменяемый объект в роли ключа. Исправление — явно преобразовать тип или исправить место, где значение получено. Чтобы ловить такие ошибки до запуска, добавьте аннотации типов и mypy. Другие исключения и общий порядок отладки собраны в руководстве ошибки в Python: как читать traceback.

  • #Python
  • #TypeError
  • #Исключения
  • #Отладка
  • #Типы данных
↑ ↓ выборEnter открытьEsc закрыть