Где в Python хранятся атрибуты класса и как устроен доступ к ним?

Ответ

В Python атрибуты класса хранятся в специальном словаре __dict__, который принадлежит самому объекту класса. Этот словарь сопоставляет имена атрибутов с их значениями.

Ключевые моменты:

  1. Хранение: Атрибуты, определенные непосредственно в теле класса, попадают в __dict__ этого класса.
  2. Доступ: К ним можно получить доступ как через класс (MyClass.attr), так и через его экземпляры (my_instance.attr).

Пример:

class Dog:
    # Атрибут класса, общий для всех экземпляров
    species = "Canis familiaris"

    def __init__(self, name):
        # Атрибут экземпляра, уникальный для каждого объекта
        self.name = name

# Доступ к __dict__ класса
# print(Dog.__dict__)
# Вывод будет содержать 'species': 'Canis familiaris', __init__, и др.

# Создание экземпляров
d1 = Dog("Rex")
d2 = Dog("Buddy")

# Атрибут 'species' берется из __dict__ класса Dog
print(d1.species)  # -> Canis familiaris
print(d2.species)  # -> Canis familiaris

# Атрибут 'name' находится в __dict__ конкретного экземпляра
print(d1.__dict__) # -> {'name': 'Rex'}
print(d2.__dict__) # -> {'name': 'Buddy'}

Механизм поиска атрибутов:

Когда вы обращаетесь к атрибуту через экземпляр (например, d1.species), Python выполняет поиск в следующем порядке:

  1. Сначала в словаре __dict__ самого экземпляра (d1).
  2. Если атрибут не найден, поиск продолжается в __dict__ его класса (Dog).
  3. Если и там его нет, поиск идет по иерархии родительских классов в соответствии с MRO (Method Resolution Order).

Это объясняет, почему все экземпляры имеют доступ к атрибутам класса, но у каждого из них есть свой собственный набор атрибутов экземпляра.