Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python class attribute

Tags:

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?

like image 990
chnet Avatar asked May 27 '10 18:05

chnet


People also ask

What is an attribute in a class?

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.

How do I get the attribute of a class in Python?

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.

How do I change class attributes in Python?

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.


2 Answers

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__.

like image 73
unutbu Avatar answered Sep 27 '22 18:09

unutbu


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.

like image 22
jakecar Avatar answered Sep 27 '22 19:09

jakecar