Как получить атрибут объекта без учета наследования в Python
Рассмотрим ситуацию с Python-классом, который содержит словарь команд группы. Возникает вопрос: как получить атрибут исключительно у самого объекта, игнорируя наследование от родительского класса?
Исходный код
Имеется следующая структура классов:
class Система:
"""Группа команд."""
Команды = {}
def __init__(self, *args, **kwargs):
pass
def пользовательИмеетДоступ(self, bot, event):
return True
def __init_subclass__(cls, *args, **kwargs):
if not hasattr(cls, 'Команды'):
return
print(cls, *args, **kwargs)
cls.Команды[cls.__name__] = cls
print(cls.__name__, cls.Команды)
class Another(Система):
pass
# Задача: getattr(Another, 'Команды') должно вернуть NoneПроблема
При вызове getattr(Another, 'Команды') возвращается значение атрибута из родительского класса Система, а не None. Это происходит потому, что стандартная функция getattr() проверяет всю цепочку наследования.
Решение
Для получения атрибута только у конкретного класса (без учета родительских) можно использовать несколько подходов:
- Проверка через
__dict__:Another.__dict__.get('Команды', None) - Использование
vars():vars(Another).get('Команды', None) - Метод
hasattrс явной проверкой:value = Another.Команды if 'Команды' in Another.__dict__ else None
Эти методы проверяют только собственные атрибуты класса Another, игнорируя унаследованные от Система.
Примечание
В представленном примере класс Another не переопределяет атрибут Команды, поэтому все указанные методы действительно вернут None. Если бы класс определял собственный атрибут Команды, методы вернули бы его значение.