Список, который указан, как атрибут экземпляра класса остается общим для всех остальных экземпляров данного класса
Создаю класс, атрибутом которого является список с уникальными значениями для каждого экземпляра.
class FooClass:
def __init__(self, list_attr=[]):
# Список, который должен быть уникальным для каждого нового экземпляра класса FooClass
self.list_attr = list_attr
def add_to_list_attr(self, new_item):
"""метод, для добавления объектов в список self.list_attr,
который предполагался как уникальный для каждого экземпляра
класса FooClass"""
self.list_attr.append(new_item)
Если я правильно понимаю смысл ключевого слова self в Питоне, то оно должно сделать список self.list_attr уникальным для каждого нового создаваемого объекта FooClass. Поэтому в методе add_to_list_attr(self, new_item) первым аргументом также указано self.
Однако на выходе я получаю это:
>>> foo1 = FooClass()
>>> foo1.list_attr
[]
>>> foo1.add_to_list_attr(1)
>>> foo1.list_attr
[1]
>>> foo2 = FooClass()
>>> foo2.list_attr
[1]
>>> foo2.add_to_list_attr(2)
>>> foo2.list_attr
[1, 2]
>>> foo1.list_attr
[1, 2]
То есть self.list_attr ведет себя, словно это статичный атрибут для класса в целом, а не атрибут экземпляра класса. Объясните, пожалуйста, в чем причина и как добиться желаемого поведения.
Ответы (1 шт):
Это известная фича, если вкратце, то нужно делать так:
def __init__(self, list_attr=None):
# Список, который должен быть уникальным для каждого нового экземпляра класса FooClass
if list_attr is None:
list_attr = []
self.list_attr = list_attr
Смысл примерно в том, что если вы задаёте дефолтный параметр функции, то он инициализируется только один раз. При создании новых экземпляров класса новой инициализации уже не происходит. Поэтому в дефолтных параметрах нужно использовать не пустой список, а None, а уже внутри функции проверять на None и создавать новый список. Это просто нужно знать.
И проявляется это не только в методах класса, а в любых функциях:
def myfunc(mylist = []):
mylist.append(1)
return mylist
myfunc()
print(myfunc())
Вывод:
[1, 1]