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
aandbbelong to the instance ofFoo, then the correct way to do this is:The following makes
aandbbelong to the class itself, so all instances share the same variables: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:
you are not changing
Foo.b, you are adding a brand new attribute tofoothat "shadows"Foo.b. When you do this, neitherbar.bnorFoo.bchange. If you subsequently dodel foo.b, that'll delete that attribute andfoo.bwill once again refer toFoo.b.