Suppose I have the following class:
class A: arr = 
If I append to
arr for an instance of
A, all instances of
A are updated.
>>> a1, a2 = A(), A() >>> a1.arr.append(0) >>> a1.arr  >>> a2.arr  >>> A.arr 
However, if I set
arr to an array literal for an instance of
A, other instances are not updated:
>>> a1.arr = [1,2,3] >>> a1.arr [1, 2, 3] >>> a2.arr  >>> A.arr 
Why does this occur? When the class attribute is a list, why are there different results between
I also noticed similar behavior when the class attribute is not an array:
class B: value = ''
>>> b1, b2 = B(), B() >>> b1.value = 'hello' >>> b1.value 'hello' >>> b2.value '' >>> B.value ''
>>> B.value = 'goodbye' >>> b1.value 'hello' >>> b2.value 'goodbye' >>> B.value 'goodbye'
Why does the behavior seem different when the class attribute is a string? When
b1's value is already set, why does
B.value = ... only update
b2's value and not
If your asking how to avoid this?
class A: def __init__(self): self.ls =  a,b = A(), A() a.ls.append(0)
__init__() will make the instances individual
I believe this answer explains what's happening.
In the class
arr is a class attribute:
...all instances of Foo [A] share foovar [arr]
.append(), you're operating directly on the list object
arr. When you assign (
a1.arr = [1, 2, 3]), you're creating a new list object and assigning it as an instance attribute (effectively
a1 that takes priority over the class attribute
If we don't touch foovar, it's the same for both f and Foo. But if we change f.foovar... << code snippet >> ...we add an instance attribute that effectively masks the value of Foo.foovar. Now if we change Foo.foovar directly, it doesn't affect our foo instance:
class C: class_attribute=2 def __init__(self): self.instance_attribute='foo'
if you query an attribute of a class instance (
my_instance.foo), the returned value is instance attribute if it exists, if not class attribute
if you assign to an instance(
my_instance.foo = 42), a instance attribute is created, it can have the same name, and it shadows the class attribute