i have a question about class attribute in python.
class base :
def __init__ (self):
pass
derived_val = 1
t1 = base()
t2 = base()
t2.derived_val +=1
t2.__class__.derived_val +=2
print t2.derived_val # its value is 2
print t2.__class__.derived_val # its value is 3
The results are different. I also use id()
function to find t2.derived_val
and t2.__class__.derived_val
have different memory address.
My problem is derived_val
is class attribute. Why it is different in above example?
Is it because the instance of class copy its own derived_val
beside the class attribute?
Any variable that is bound in a class is a class attribute . Any function defined within a class is a method . Methods receive an instance of the class, conventionally called self , as the first argument.
Attributes of a class can also be accessed using the following built-in methods and functions : getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute.
But be careful, if you want to change a class attribute, you have to do it with the notation ClassName. AttributeName. Otherwise, you will create a new instance variable.
There are class attributes, and instance attributes. When you say
class base :
derived_val = 1
You are defining a class attribute. derived_val
becomes a key in
base.__dict__
.
t2=base()
print(base.__dict__)
# {'derived_val': 1, '__module__': '__main__', '__doc__': None}
print(t2.__dict__)
# {}
When you say t2.derived_val
Python tries to find 'derived_val' in t2.__dict__
. Since it is not there, it looks if there is a 'derived_val'
key in any of t2
's base classes.
print(t2.derived_val)
print(t2.__dict__)
# 1
# {}
But when you assign a value to t2.derived_val
, you are now adding an instance attribute to t2
. A derived_val
key is added to t2.__dict__
.
t2.derived_val = t2.derived_val+1
print(t2.derived_val)
print(t2.__dict__)
# 2
# {'derived_val': 2}
Note that at this point, there are two derived_val
attributes, but only
the instance attribute is easily accessible. The class attribute becomes accessible only through referencing base.derived_val
or direct access to the class dict base.__dict__
.
Check it out here and here.
The __class__
attribute is the class that the object belongs to. So in your example, the situation is similar to static variables. The t2.__class__.derived_val
is referring to the variable that belongs to the class, not the variable that belongs to t2.
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