class variables is shared across all instances in python?
Solution 1
var
should definitely not be shared as long as you access it by instance.var
or self.var
. With the list however, what your statement does is when the class gets evaluated, one list instance is created and bound to the class dict, hence all instances will have the same list. Whenever you set instance.list = somethingelse
resp. self.list = somethingelse
, it should get an instance level value.
Example time:
>>> class A():
... var = 0
... list = []
...
>>> a = A()
>>> b = A()
>>> a.var
0
>>> a.list
[]
>>> b.var
0
>>> b.list
[]
>>> a.var = 1
>>> b.var
0
>>> a.list.append('hello')
>>> b.list
['hello']
>>> b.list = ['newlist']
>>> a.list
['hello']
>>> b.list
['newlist']
Solution 2
These are basically like static variables in Java:
// Example equivalent Java
class A {
static int var = 0;
static String[] list;
}
This is the intended behavior: Class variables are for the class.
For normal instance variables, declare them in the constructor:
class A:
def __init__(self):
self.var = 0
self.list = []
You may want to look at Static class variables in Python.
Solution 3
The reason is that in Python class
is an executable statement that is executed like any other. The body of the class definition is executed once, when the class is defined. If you have a line line var = []
in there, then it is only executed once, so only one list can ever be created as a result of that line.
Solution 4
Note that you do not see this behaviour for var
, you only see it for list
:
>>> class A:
... var = 0
... list = []
...
>>> a1 = A()
>>> a2 = A()
>>> a1.var = 3
>>> a2.var
0
howtechstuffworks
I am Student from an university in North East. I had a bad habit of coding in a language, just by seeing examples and browsing/googling syntax online, thats how I completed most of my assignments, but better late than never, I realized that this is a problem, when you go into research, where you need to think in terms of language and understand the underlying mechanisms to become a better coder, which is what after all, I am striving for. Anyways, I think I will learn more here, than I could ever contribute.
Updated on October 28, 2020Comments
-
howtechstuffworks over 3 years
I started coding in python a week ago, it is my mistake i started coding using oops,classes and objects that soon. I assumed my C++ proficiency will help.... I got bit by the following code
class A: var=0 list=[] def __init__(self): pass
Here to my surprise, var and list are kinda global variable, it is shared across all instances it seems.... What I thought was it was different across all the instances..... It took me half a day to figure out that.... It does not make even slightest sense, that a variable can be accessed by a class object only, but is shared across all instances....... Just Curious, is there a reason behind it?????
-
howtechstuffworks almost 12 years^yeah agreed.... but still confusing....
-
Brendan Long almost 12 yearsThis is because Python looks for an instance variable before the class variable. In your
var
case, you're adding an instance variable, which then takes precedence. -
howtechstuffworks almost 12 yearsokay, now I tried an exmaple and pretty sure, the list is shared across all.... How about the variable? it is not shared across all instances(I tested it)..... is it still static, do I need to learn anymore before proceeding back to the code.... Thanks for your help.......
-
Brendan Long almost 12 years@howtechstuffworks The other variable is static too, but if you do
self.var="something else"
, then you're setting up an instance variable with the same name (you will have bothA.var
andself.var
), and it will assume that you mean the instance variable. You can still access the class variable withA.var
. You can do the same thing with thelist
by declaring an instance method with the same name (self.list = "something else"
). -
Brendan Long almost 12 yearsThe exact same thing is happening with
var
as withlist
, the difference is that you can't append tovar
like you can withlist
, you can only declare another variable with the same name. -
howtechstuffworks almost 12 yearsYeah actually I moved everything under '__init__()', just another question, I have some variables that needs to be common and not writable..... think like a macro in C or const in C++, where should I write it here????
-
Brendan Long almost 12 years@howtechstuffworks You should generally open a new thread for each question, but to answer -- Python doesn't have constants. There are some hacks to create them, but the general solution is to name constants in upper case and assume users of your API aren't stupid enough to change them (you'll find this is a common theme in Python -- you can do anything, but just because you can doesn't mean you should).
-
mensi almost 12 years@BrendanLong immutable types are different in this situation, since it does not matter if you share them
-
Brendan Long almost 12 yearsYes, I just want to clarify that you are sharing the immutable
var
, you're just also replacing it with something else whenever you doself.var = ...
. So the behavior is exactly the same forvar
andlist
, it's just thatlist
is more interesting as a shared variable (since it's mutable). -
F.S. almost 7 years@BrendanLong why is
var
an instance variable, andlist
is not, if they are defined in the same way? -
Gertjan Franken almost 4 yearsThis behavior of mutable default arguments is also discussed here: docs.python-guide.org/writing/gotchas/…