AttributeError: object has no attribute означает, что объект слева от точки существует, но у его фактического типа нет запрошенного имени. Разделите выражение, выведите type(obj) и repr(obj), затем проверьте точное имя атрибута в документации или классе. Чаще всего виноваты опечатка, неожиданный тип или функция, которая вернула None.
В строке user.name.upper() есть два последовательных доступа: сначала user.name, затем upper у результата. Сообщение называет тип объекта и отсутствующий атрибут. Это позволяет не искать по всему проекту: нужно определить выражение непосредственно слева от проблемной точки и проследить, откуда оно пришло.
Что фактически находится слева от точки в момент ошибки.
Какие методы и поля реально поддерживает этот класс.
Какая функция, ветка или преобразование создали значение.
Как прочитать сообщение AttributeError
Формулировка вида "list" object has no attribute "strip" уже сообщает две вещи: объект является списком, а код запросил строковый метод strip. Исправление зависит от намерения: выбрать один элемент, обработать каждую строку либо изменить функцию, которая должна была вернуть строку.
names = [' Анна ', ' Борис ']
print(type(names), repr(names))
# <class 'list'> [' Анна ', ' Борис ']
print(names.strip())
# AttributeError: 'list' object has no attribute 'strip'| Сообщение | Фактический объект | Первый вопрос |
|---|---|---|
'list' ... 'strip' | Список | Нужно обработать элемент или весь список? |
'str' ... 'append' | Строка | Почему ожидался список? |
'NoneType' ... | None | Какая функция ничего не вернула? |
'dict' ... 'name' | Словарь | Нужен ключ ["name"] или объект класса? |
Class ... | Экземпляр вашего класса | Создано ли поле во всех ветках конструктора? |

Сообщение сразу сужает поиск до фактического типа и одного отсутствующего имени.
user может содержать словарь, строку или None. Имя выражает намерение автора, а type показывает состояние программы. Диагноз строится по фактическому значению в момент сбоя.Проверка объекта слева от точки
- Найдите последнюю строку вашего файла в Traceback.
- Определите имя атрибута из последней строки ошибки.
- Разбейте длинную цепочку точек на промежуточные переменные.
- Выведите
typeиreprобъекта перед доступом. - Найдите присваивание, аргумент или return, который создал значение.
- Повторите тот же сценарий после одной исправленной причины.
Для длинной цепочки временные переменные полезнее dir. Они показывают, на каком шаге тип перестал соответствовать ожиданию. dir(obj) можно использовать как подсказку в интерактивной отладке, но не как проверку бизнес-логики: список имён велик и включает внутренние методы.
profile = load_profile()
print(type(profile), repr(profile))
name = profile.get('name')
print(type(name), repr(name))
if name is not None:
print(name.upper())
Промежуточные переменные показывают, на каком шаге тип стал неожиданным.
Если profile оказался списком вместо словаря, замена get на случайный метод списка не исправит контракт. Проследите функцию load_profile и все её ветки return.
Почему NoneType не имеет нужного атрибута
None часто появляется, когда функция не выполнила return, метод изменяет объект на месте или поиск ничего не нашёл. Например, list.sort() сортирует список и возвращает None. Присваивание результата обратно переменной уничтожает ссылку на список.
| Источник None | Пример | Исправление |
|---|---|---|
| Нет return в функции | value = save() | Вернуть значение или не ожидать его |
| Метод меняет на месте | items = items.sort() | Вызвать items.sort() отдельно |
| Поиск ничего не нашёл | match = find(...) | Обработать штатное отсутствие |
| Ветка без присваивания | Значение осталось None | Покрыть все ветки |
| Необязательное поле | dict.get | Проверить None или задать default |
scores = [72, 91, 84]
# sort изменяет список и возвращает None
scores.sort()
print(scores)
# [72, 84, 91]
last_score = scores[-1]
print(last_score)
# 91
Нет return, in-place метод и пустой поиск требуют разных исправлений.
Опечатки и методы не того типа
У списков есть append, у строк strip, у словарей get. Похожие операции могут называться по-разному: строка не имеет push, а список не имеет length как свойства JavaScript. Сверяйтесь с документацией именно текущего языка и типа.
Проверка скрывает неожиданный тип. Сначала восстановите контракт данных.
Похожее имя метода может иметь другой смысл и набор аргументов.
Так можно скрыть опечатку внутри вызываемой функции, не связанную с исходным объектом.
Часто неверен источник значения, а не определение класса. Проверьте место создания экземпляра.
Понятные имена, type hints и небольшой контракт возвращаемого значения позволяют редактору подсветить часть ошибок заранее. Они не заменяют проверку входных данных, но уменьшают вероятность вызвать метод не того типа.
Практика: исправляем обработку списка имён
Если функция возвращает список строк, обработайте каждый элемент. Не вызывайте строковый метод у контейнера. Затем добавьте тест с пустым списком и строкой из одних пробелов. Так исправление подтверждает не только отсутствие AttributeError, но и правильный результат.
- Из сообщения выписаны фактический тип и отсутствующий атрибут.
- Длинная цепочка разбита на промежуточные значения.
- Перед проблемной точкой проверены type и repr.
- Найдено место, где объект создаётся или возвращается.
- Документация открыта для фактического типа, а не предполагаемого.
- Проверены обычное значение, пустой контейнер и None по контракту.
[name.strip() for name in names], а не просто удаление .strip(). Запишите ожидаемый результат и сравните его после правки.Что находится слева от точки в сообщении?
Объект, у которого Python пытался найти атрибут или метод.
Почему появляется NoneType?
Предыдущее выражение вернуло None: из-за отсутствующего return, метода in-place или штатного отсутствия результата.
Поможет ли hasattr всегда?
Нет. Он может скрыть нарушение контракта и пропустить нужную операцию.
Что возвращает list.sort?
None. Метод сортирует существующий список на месте.
Зачем использовать repr?
Он показывает точное представление значения, включая кавычки, пробелы и None.
Закрепите функции, коллекции и классы в курсе Python. Для словарей пригодится статья о словарях в Python, а для списков разбор первой суперсилы новичка.
Общий маршрут поиска повторите по материалу про частые ошибки. В Кодике удобно записывать ожидаемый тип рядом с реальным type и минимальной цепочкой присваиваний.