I have a Python class that has a class attribute set to something other than None
. When creating a new instance, the changes made to that attribute perpetuates through all instances.
Here's some code to make sense of this:
class Foo(object):
a = []
b = 2
foo = Foo()
foo.a.append('item')
foo.b = 5
Using foo.a
returns ['item']
and foo.b
returns 5
, as one would expect.
When I create a new instance (we'll call it bar
), using bar.a
returns ['item']
and bar.b
return 5
, too! However, when I initially set all the class attributes to None
then set them to whatever in __init__
, like so:
class Foo(object):
a = None
b = None
def __init__(self):
self.a = []
self.b = 2
Using bar.a
returns []
and bar.b
returns 2
while foo.a
returns ['item']
and foo.b
returns 5
.
Is this how it's suppose to work? I've apparently never ran into this issue in the 3 years I've programmed Python and would like some clarification. I also can't find it anywhere in the documentation, so giving me a reference would be wonderful if possible. :)
Yes, this is how it is supposed to work.
If a
and b
belong to the instance of Foo
, then the correct way to do this is:
class Foo(object):
def __init__(self):
self.a = []
self.b = 2
The following makes a
and b
belong to the class itself, so all instances share the same variables:
class Foo(object):
a = []
b = 2
When you mix the two methods -- as you did in your second example -- this doesn't add anything useful, and just causes confusion.
One caveat worth mentioning is that when you do the following in your first example:
foo.b = 5
you are not changing Foo.b
, you are adding a brand new attribute to foo
that "shadows" Foo.b
. When you do this, neither bar.b
nor Foo.b
change. If you subsequently do del foo.b
, that'll delete that attribute and foo.b
will once again refer to Foo.b
.