Ситуация: мы пишем простую программу на Python для автосервисов. Всё несложно: создаём новый класс и на основе него создаём новые объекты. Но когда мы хотим обратиться к какому-то свойству, вдруг возникает ошибка:
class Car:
def __init__(self, model):
self.model = model
my_car = Car("Toyota")
print(my_car.color) # Ошибка!
❌ AttributeError: 'Car' object has no attribute 'color'
Что это значит: Python сообщает, что вы пытаетесь обратиться к атрибуту или методу, который не существует в данном объекте. Это происходит, когда:
- Атрибут не был определён в классе.
- Вы опечатались в имени атрибута.
- Атрибут удалён (с помощью del).
Разберём по очереди все эти случаи.
Обращение к несуществующему атрибуту
Происходит, когда мы используем атрибут, который нигде не определён, — и при обращении к нему Python логично начинает возмущаться:
class Dog:
def __init__(self, name):
self.name = name
my_dog = Dog("Rex")
print(my_dog.age) # AttributeError: у класса нет атрибута 'age'
Опечатка в имени атрибута
Самая частая ошибка на самом деле в этом случае. Спешишь, промахиваешься, нажимаешь не на ту клавишу — и готово:
class User:
def __init__(self, username):
self.username = username
user = User("admin")
print(user.usermame) # AttributeError: опечатка в имени (usemame вместо username)
Попытка вызвать несуществующий метод у стандартных объектов
Иногда бывает так, что ты вот почему-то искренне уверен, что у какого-то стандартного объекта есть конкретный встроенный атрибут. А его нет. А ты уверен, что есть. В этом случае правда на стороне Python:
text = "Hello"
text.make_upper() # AttributeError: у строк нет метода make_upper()
Как исправить ошибку AttributeError
Чтобы исправить ошибку AttributeError, достаточно этих трёх шагов:
- Проверьте правильность написания атрибута.
- Используйте функцию hasattr() для проверки.
if hasattr(my_car, 'color'):
print(my_car.color)
else:
print("Атрибут color не существует")
- Добавьте атрибут в класс, если его нет, но вам очень хочется его использовать.
- Для динамических атрибутов используйте setattr():
setattr(my_car, 'color', 'red') #
Добавляем атрибут динамически
Продвинутые случаи работы с ошибкой AttributeError
Работа с __getattr__
Можно определить специальный метод для обработки обращения к несуществующим атрибутам:
class SmartDict:
def __getattr__(self, name):
return f"Атрибут {name} не существует, но мы его обработали"
obj = SmartDict()
print(obj.anything) # Не вызовет ошибку
Использование property
Для безопасного доступа к атрибутам можно использовать декоратор @property:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
Бонус для читателей
Если вам интересно погрузиться в мир ИТ и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой и даст безлимит на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.
Вам слово
Приходите к нам в соцсети поделиться своим мнением об ошибке и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте — шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!