I have the following classes:
class A(object):
x = 1
class B(A):
pass
class C(A):
pass
When I print the value of x
from each class I get:
>>>A.x, B.x, C.x
(1,1,1)
Then I assign 2
to B.x
B.x = 2
A.x, B.x, C.x
>>>(1,2,1)
Everything was normal but when I assigned 3
to A.x
I got this :
A.x=3
A.x, B.x, C.x
>>>(3,2,3)
I thought it would return (3,2,1)
.
We should be careful when changing the value of a class variable. If we try to change a class variable using an object, a new instance (or non-static) variable for that particular object is created and this variable shadows the class variables. Below is a Python program to demonstrate the same.
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.
Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
In Python, Class variables are declared when a class is being constructed. They are not defined inside any methods of a class because of this only one copy of the static variable will be created and shared between all objects of the class.
Class Variables: A class variable is a variable that is declared inside of class, but outside of any instance method or __init__ () method. Instance variable vs. class variables What is an Class Variable in Python? What is an Class Variable in Python?
Class or Static Variables in Python. Class or static variables are shared by all objects. Instance or non-static variables are different for different objects (every object has a copy of it). For example, let a Computer Science Student be represented by class CSStudent.
Class variables are shared by all instances of a class. Unlike instance variable, the value of a class variable is not varied from object to object, In Python, Class variables are declared when a class is being constructed.
In Python, we can define the variable outside the class, inside the class, and even inside the methods. Let’s see, how to use and access these variables throughout the program. The variables that are defined outside the class can be accessed by any class or any methods in the class by just writing the variable name.
This is fundamentally how inheritance works in Python: for class-level variables, it first checks' the classes namespace, then the namespace of every class in the method resolution order. So, both B
and C
inherit x
from A
:
In [1]: class A(object):
...: x = 1
...: class B(A):
...: pass
...: class C(A):
...: pass
...:
In [2]: vars(A)
Out[2]:
mappingproxy({'__module__': '__main__',
'x': 1,
'__dict__': <attribute '__dict__' of 'A' objects>,
'__weakref__': <attribute '__weakref__' of 'A' objects>,
'__doc__': None})
In [3]: vars(B)
Out[3]: mappingproxy({'__module__': '__main__', '__doc__': None})
In [4]: vars(C)
Out[4]: mappingproxy({'__module__': '__main__', '__doc__': None})
When you ask for B.x
or C.x
, it looks into that class namespace, doesn't find any "x"
, then tries A
's namespace, finds it, and returns it.
Now, when you assign a variable to B.x = 2
, that adds it to B
's class namespace directly:
In [5]: B.x = 2
...:
In [6]: vars(B)
Out[6]: mappingproxy({'__module__': '__main__', '__doc__': None, 'x': 2})
And similarly, when you assign it to A.x=3
, it overwrites the old value:
In [7]: A.x=3
...:
In [8]: vars(A)
Out[8]:
mappingproxy({'__module__': '__main__',
'x': 3,
'__dict__': <attribute '__dict__' of 'A' objects>,
'__weakref__': <attribute '__weakref__' of 'A' objects>,
'__doc__': None})
In [9]: vars(B)
Out[9]: mappingproxy({'__module__': '__main__', '__doc__': None, 'x': 2})
In [10]: vars(C)
Out[10]: mappingproxy({'__module__': '__main__', '__doc__': None})
So now, same as before, when you look for C.x
, it doesn't find it's own, then it looks for x
inside A
, and finds it.
Note, inheritance works like this with instances too, just it checks the instance namespace first, then the instances class's namespace, then all the namespace of the classes in it's method resolution order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With