Проблема в том, что bar
определяется как атрибут класса, а не переменная экземпляра.
В foo
атрибут класса модифицирован в методе init
, поэтому все экземпляры затронуты.
В foo2
переменная экземпляра определяется с помощью атрибута (пустого) класса, и каждый экземпляр получает свой собственный bar
.
«Правильный» реализация будет:
class foo:
def __init__(self, x):
self.bar = [x]
Конечно, атрибуты класса являются полностью законными. Фактически вы можете получить доступ и изменить их, не создавая экземпляр класса следующим образом:
class foo:
bar = []
foo.bar = [x]