Почему список заметок в классе Python сохраняет элементы между разными экземплярами класса?

Добрый день. Я изучаю ООП в Python и не могу понять, почему у всех экземпляров User в атрибуте notes оказывается один и тот же список, хотя значения login у разных пользователей различаются. Привожу код: <br/> <pre><code class="python">class User:
  • 8 июня 2026 г. 13:01
Ответы на вопрос 3
Коротко — потому что вы создали список как атрибут класса, а не как атрибут экземпляра. Атрибуты класса общие для всех экземпляров; если этот атрибут — изменяемый объект (список, словарь и т. п.), то изменения будут видны у всех объектов.

Почему так происходит (пошагово):
- Когда вы пишете class User: notes = [], вы создаёте один объект списка и привязываете его к имени User.notes.
- При обращении self.notes Python сначала ищет атрибут в словаре экземпляра (self.__dict__), не находит и берёт User.notes.
- При вызове self.notes.append(...) вы не создаёте новое поле в экземпляре, вы берёте ссылку на общий список и изменяете его — поэтому все экземпляры увидят изменение.
- Если вы присвоите self.notes = [...], то это создаст независимый атрибут в экземпляре, который скроет атрибут класса.

Пример, иллюстрирующий проблему и исправление:

Неправильно (делит список между всеми экземплярами):
```python
class User:
    notes = []          # общий для всех

    def __init__(self, login):
        self.login = login
```

Правильно (у каждого экземпляра свой список):
```python
class User:
    def __init__(self, login):
        self.login = login
        self.notes = []  # новый список для каждого экземпляра
```

Альтернативы и полезные приёмы:
- Для dataclass:
```python
from dataclasses import dataclass, field

@dataclass
class User:
    login: str
    notes: list = field(default_factory=list)
```
- Если по какой-то причине вы хотите начинать с общего списка, но иногда копировать его — используйте copy.copy или list(User.notes).
- Проверка того, что это один и тот же объект: print(id(user1.notes), id(user2.notes)) — если id одинаковые, это один список.

Резюме: создавайте изменяемые коллекции в __init__ (или через default_factory), если хотите, чтобы они были независимыми для каждого экземпляра.
это mutable default argument — notes=[] создаётся один раз при определении __init__, не при каждом вызове. все инстансы без явного третьего аргумента ссылаются на один и тот же список. <br/> <br/> фикс: <code>def __init__(self, lgn, psw, notes=None):</code> и внутри <code>self.notes = [] if notes is None else notes</code>
1. Почитай про свойство python объекта, мутабельность/не мутабельность. <br/> 2. Почитай  про мутабельные объекты, как параметр в функции по умолчанию к чему это ведет и практики по решению проблем. <br/> 3. Примени на своем ООП коде.
Похожие вопросы