Почему список как атрибут класса оказался общим для всех экземпляров?
Сделал так:
class Basket:
items = []
def add(self, x):
self.items.append(x)
a = Basket()
b = Basket()
a.add('яблоко')
print(b.items) # ['яблоко'] — почему?!
Добавляю в a, а оно появляется и в b. Я же создал два разных объекта. В чём подвох?
3 ответа
items = [] объявлен на уровне класса, а не в __init__, поэтому это один общий список, разделяемый всеми экземплярами. self.items.append(...) не создаёт новый список — он находит общий через класс и мутирует его, поэтому изменение видно у всех.
Правильно — заводить изменяемые атрибуты в __init__, тогда у каждого объекта свой список:
class Basket:
def __init__(self):
self.items = [] # свой список на каждый экземпляр
def add(self, x):
self.items.append(x)
Это классическая грабля. Атрибуты класса хороши для констант/неизменяемых значений (которые общие осознанно), а всё изменяемое (списки, словари) держи в __init__.
Потому что items — атрибут класса, он один на всех. Перенеси self.items = [] в __init__.
Список создаётся заново при каждом создании объекта, у тебя где-то другая ошибка.