Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Где находятся атрибуты класса в Python
Это фундаментальный вопрос о том, как Python хранит данные классов и экземпляров. Ответ зависит от типа атрибута.
Атрибуты класса
Атрибуты, определённые в теле класса (вне методов), хранятся в словаре класса __dict__ и в специальной таблице атрибутов класса:
class Person:
species = "Homo sapiens" # атрибут класса
count = 0
def __init__(self, name):
self.name = name # атрибут экземпляра
# Атрибуты класса находятся в:
print(Person.__dict__) # {'species': 'Homo sapiens', 'count': 0, ...}
print(Person.species) # Homo sapiens
Важный момент: все экземпляры класса РАЗДЕЛЯЮТ один и тот же атрибут класса:
person1 = Person("Alice")
person2 = Person("Bob")
print(person1.species) # Homo sapiens (берётся из класса)
print(person2.species) # Homo sapiens (один и тот же объект)
# Опасная ошибка с изменяемыми атрибутами:
class Buggy:
items = [] # ОБЩИЙ для всех экземпляров!
def add_item(self, item):
self.items.append(item)
b1 = Buggy()
b2 = Buggy()
b1.add_item("A")
b2.add_item("B")
print(b1.items) # ['A', 'B'] - обе разделяют один список
Атрибуты экземпляра
Атрибуты, установленные в методе __init__ или в любом методе через self.attr = value, хранятся в словаре экземпляра __dict__:
class Person:
def __init__(self, name):
self.name = name
self.age = 25
person = Person("Alice")
print(person.__dict__) # {'name': 'Alice', 'age': 25}
# Каждый экземпляр имеет свой __dict__
person1 = Person("Alice")
person2 = Person("Bob")
print(person1.__dict__) # {'name': 'Alice', 'age': 25}
print(person2.__dict__) # {'name': 'Bob', 'age': 25}
Порядок поиска атрибутов (MRO)
Когда вы обращаетесь к атрибуту через экземпляр obj.attr, Python ищет в порядке:
- В
__dict__самого экземпляра - В
__dict__класса - В
__dict__родительских классов (по MRO) - В методе
__getattr__если определён - Если не найдено -
AttributeError
class Parent:
x = "parent"
class Child(Parent):
x = "child"
obj = Child()
obj.x = "instance" # атрибут экземпляра
print(obj.x) # instance (из __dict__ экземпляра)
print(Child.x) # child (из __dict__ класса)
print(Parent.x) # parent (из родителя)
Слоты для оптимизации
Если класс использует __slots__, атрибуты хранятся компактнее:
class Optimized:
__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
obj = Optimized("Alice", 30)
print(hasattr(obj, '__dict__')) # False - нет __dict__
Итоговая таблица
| Тип | Где хранится | Доступ | Разделение |
|---|---|---|---|
| Атрибут класса | ClassName.__dict__ | ClassName.attr или instance.attr | Общий для всех экземпляров |
| Атрибут экземпляра | instance.__dict__ | instance.attr | Уникален для каждого объекта |
| Слоты | C структура | instance.attr | Уникален, компактнее по памяти |
Помните: все экземпляры разделяют атрибуты класса, но имеют свои копии атрибутов экземпляра!